Skip to content

Commit e495274

Browse files
committed
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma
Pull rdma updates from Jason Gunthorpe: "This cycle we got a new RDMA driver "ERDMA" for the Alibaba cloud environment. Otherwise the changes are dominated by rxe fixes. There is another RDMA driver on the list that might get merged next cycle, 'MANA' for the Azure cloud environment. Summary: - Bug fixes and small features for irdma, hns, siw, qedr, hfi1, mlx5 - General spelling/grammer fixes - rdma cm can follow changes in neighbours for control packets - Significant amounts of rxe fixes and spec compliance changes - Use the modern NAPI API - Use the bitmap API instead of open coding - Performance improvements for rtrs - Add the ERDMA driver for Alibaba cloud - Fix a use after free bug in SRP" * tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: (99 commits) RDMA/ib_srpt: Unify checking rdma_cm_id condition in srpt_cm_req_recv() RDMA/rxe: Fix error unwind in rxe_create_qp() RDMA/mlx5: Add missing check for return value in get namespace flow RDMA/rxe: Split qp state for requester and completer RDMA/rxe: Generate error completion for error requester QP state RDMA/rxe: Update wqe_index for each wqe error completion RDMA/srpt: Fix a use-after-free RDMA/srpt: Introduce a reference count in struct srpt_device RDMA/srpt: Duplicate port name members IB/qib: Fix repeated "in" within comments RDMA/erdma: Add driver to kernel build environment RDMA/erdma: Add the ABI definitions RDMA/erdma: Add the erdma module RDMA/erdma: Add connection management (CM) support RDMA/erdma: Add verbs implementation RDMA/erdma: Add verbs header file RDMA/erdma: Add event queue implementation RDMA/erdma: Add cmdq implementation RDMA/erdma: Add main include file RDMA/erdma: Add the hardware related definitions ...
2 parents 746fc76 + 6b822d4 commit e495274

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+8364
-1003
lines changed

MAINTAINERS

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,14 @@ S: Maintained
736736
F: Documentation/i2c/busses/i2c-ali1563.rst
737737
F: drivers/i2c/busses/i2c-ali1563.c
738738

739+
ALIBABA ELASTIC RDMA DRIVER
740+
M: Cheng Xu <[email protected]>
741+
M: Kai Shen <[email protected]>
742+
743+
S: Supported
744+
F: drivers/infiniband/hw/erdma
745+
F: include/uapi/rdma/erdma-abi.h
746+
739747
ALIENWARE WMI DRIVER
740748
741749
S: Maintained

drivers/infiniband/Kconfig

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -78,20 +78,21 @@ config INFINIBAND_VIRT_DMA
7878
def_bool !HIGHMEM
7979

8080
if INFINIBAND_USER_ACCESS || !INFINIBAND_USER_ACCESS
81-
source "drivers/infiniband/hw/mthca/Kconfig"
82-
source "drivers/infiniband/hw/qib/Kconfig"
81+
source "drivers/infiniband/hw/bnxt_re/Kconfig"
8382
source "drivers/infiniband/hw/cxgb4/Kconfig"
8483
source "drivers/infiniband/hw/efa/Kconfig"
84+
source "drivers/infiniband/hw/erdma/Kconfig"
85+
source "drivers/infiniband/hw/hfi1/Kconfig"
86+
source "drivers/infiniband/hw/hns/Kconfig"
8587
source "drivers/infiniband/hw/irdma/Kconfig"
8688
source "drivers/infiniband/hw/mlx4/Kconfig"
8789
source "drivers/infiniband/hw/mlx5/Kconfig"
90+
source "drivers/infiniband/hw/mthca/Kconfig"
8891
source "drivers/infiniband/hw/ocrdma/Kconfig"
89-
source "drivers/infiniband/hw/vmw_pvrdma/Kconfig"
90-
source "drivers/infiniband/hw/usnic/Kconfig"
91-
source "drivers/infiniband/hw/hns/Kconfig"
92-
source "drivers/infiniband/hw/bnxt_re/Kconfig"
93-
source "drivers/infiniband/hw/hfi1/Kconfig"
9492
source "drivers/infiniband/hw/qedr/Kconfig"
93+
source "drivers/infiniband/hw/qib/Kconfig"
94+
source "drivers/infiniband/hw/usnic/Kconfig"
95+
source "drivers/infiniband/hw/vmw_pvrdma/Kconfig"
9596
source "drivers/infiniband/sw/rdmavt/Kconfig"
9697
source "drivers/infiniband/sw/rxe/Kconfig"
9798
source "drivers/infiniband/sw/siw/Kconfig"

drivers/infiniband/core/cma.c

Lines changed: 218 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <linux/in6.h>
1212
#include <linux/mutex.h>
1313
#include <linux/random.h>
14+
#include <linux/rbtree.h>
1415
#include <linux/igmp.h>
1516
#include <linux/xarray.h>
1617
#include <linux/inetdevice.h>
@@ -20,6 +21,7 @@
2021

2122
#include <net/net_namespace.h>
2223
#include <net/netns/generic.h>
24+
#include <net/netevent.h>
2325
#include <net/tcp.h>
2426
#include <net/ipv6.h>
2527
#include <net/ip_fib.h>
@@ -168,6 +170,9 @@ static struct ib_sa_client sa_client;
168170
static LIST_HEAD(dev_list);
169171
static LIST_HEAD(listen_any_list);
170172
static DEFINE_MUTEX(lock);
173+
static struct rb_root id_table = RB_ROOT;
174+
/* Serialize operations of id_table tree */
175+
static DEFINE_SPINLOCK(id_table_lock);
171176
static struct workqueue_struct *cma_wq;
172177
static unsigned int cma_pernet_id;
173178

@@ -202,6 +207,11 @@ struct xarray *cma_pernet_xa(struct net *net, enum rdma_ucm_port_space ps)
202207
}
203208
}
204209

210+
struct id_table_entry {
211+
struct list_head id_list;
212+
struct rb_node rb_node;
213+
};
214+
205215
struct cma_device {
206216
struct list_head list;
207217
struct ib_device *device;
@@ -420,11 +430,21 @@ static inline u8 cma_get_ip_ver(const struct cma_hdr *hdr)
420430
return hdr->ip_version >> 4;
421431
}
422432

423-
static inline void cma_set_ip_ver(struct cma_hdr *hdr, u8 ip_ver)
433+
static void cma_set_ip_ver(struct cma_hdr *hdr, u8 ip_ver)
424434
{
425435
hdr->ip_version = (ip_ver << 4) | (hdr->ip_version & 0xF);
426436
}
427437

438+
static struct sockaddr *cma_src_addr(struct rdma_id_private *id_priv)
439+
{
440+
return (struct sockaddr *)&id_priv->id.route.addr.src_addr;
441+
}
442+
443+
static inline struct sockaddr *cma_dst_addr(struct rdma_id_private *id_priv)
444+
{
445+
return (struct sockaddr *)&id_priv->id.route.addr.dst_addr;
446+
}
447+
428448
static int cma_igmp_send(struct net_device *ndev, union ib_gid *mgid, bool join)
429449
{
430450
struct in_device *in_dev = NULL;
@@ -445,6 +465,117 @@ static int cma_igmp_send(struct net_device *ndev, union ib_gid *mgid, bool join)
445465
return (in_dev) ? 0 : -ENODEV;
446466
}
447467

468+
static int compare_netdev_and_ip(int ifindex_a, struct sockaddr *sa,
469+
struct id_table_entry *entry_b)
470+
{
471+
struct rdma_id_private *id_priv = list_first_entry(
472+
&entry_b->id_list, struct rdma_id_private, id_list_entry);
473+
int ifindex_b = id_priv->id.route.addr.dev_addr.bound_dev_if;
474+
struct sockaddr *sb = cma_dst_addr(id_priv);
475+
476+
if (ifindex_a != ifindex_b)
477+
return (ifindex_a > ifindex_b) ? 1 : -1;
478+
479+
if (sa->sa_family != sb->sa_family)
480+
return sa->sa_family - sb->sa_family;
481+
482+
if (sa->sa_family == AF_INET)
483+
return memcmp((char *)&((struct sockaddr_in *)sa)->sin_addr,
484+
(char *)&((struct sockaddr_in *)sb)->sin_addr,
485+
sizeof(((struct sockaddr_in *)sa)->sin_addr));
486+
487+
return ipv6_addr_cmp(&((struct sockaddr_in6 *)sa)->sin6_addr,
488+
&((struct sockaddr_in6 *)sb)->sin6_addr);
489+
}
490+
491+
static int cma_add_id_to_tree(struct rdma_id_private *node_id_priv)
492+
{
493+
struct rb_node **new, *parent = NULL;
494+
struct id_table_entry *this, *node;
495+
unsigned long flags;
496+
int result;
497+
498+
node = kzalloc(sizeof(*node), GFP_KERNEL);
499+
if (!node)
500+
return -ENOMEM;
501+
502+
spin_lock_irqsave(&id_table_lock, flags);
503+
new = &id_table.rb_node;
504+
while (*new) {
505+
this = container_of(*new, struct id_table_entry, rb_node);
506+
result = compare_netdev_and_ip(
507+
node_id_priv->id.route.addr.dev_addr.bound_dev_if,
508+
cma_dst_addr(node_id_priv), this);
509+
510+
parent = *new;
511+
if (result < 0)
512+
new = &((*new)->rb_left);
513+
else if (result > 0)
514+
new = &((*new)->rb_right);
515+
else {
516+
list_add_tail(&node_id_priv->id_list_entry,
517+
&this->id_list);
518+
kfree(node);
519+
goto unlock;
520+
}
521+
}
522+
523+
INIT_LIST_HEAD(&node->id_list);
524+
list_add_tail(&node_id_priv->id_list_entry, &node->id_list);
525+
526+
rb_link_node(&node->rb_node, parent, new);
527+
rb_insert_color(&node->rb_node, &id_table);
528+
529+
unlock:
530+
spin_unlock_irqrestore(&id_table_lock, flags);
531+
return 0;
532+
}
533+
534+
static struct id_table_entry *
535+
node_from_ndev_ip(struct rb_root *root, int ifindex, struct sockaddr *sa)
536+
{
537+
struct rb_node *node = root->rb_node;
538+
struct id_table_entry *data;
539+
int result;
540+
541+
while (node) {
542+
data = container_of(node, struct id_table_entry, rb_node);
543+
result = compare_netdev_and_ip(ifindex, sa, data);
544+
if (result < 0)
545+
node = node->rb_left;
546+
else if (result > 0)
547+
node = node->rb_right;
548+
else
549+
return data;
550+
}
551+
552+
return NULL;
553+
}
554+
555+
static void cma_remove_id_from_tree(struct rdma_id_private *id_priv)
556+
{
557+
struct id_table_entry *data;
558+
unsigned long flags;
559+
560+
spin_lock_irqsave(&id_table_lock, flags);
561+
if (list_empty(&id_priv->id_list_entry))
562+
goto out;
563+
564+
data = node_from_ndev_ip(&id_table,
565+
id_priv->id.route.addr.dev_addr.bound_dev_if,
566+
cma_dst_addr(id_priv));
567+
if (!data)
568+
goto out;
569+
570+
list_del_init(&id_priv->id_list_entry);
571+
if (list_empty(&data->id_list)) {
572+
rb_erase(&data->rb_node, &id_table);
573+
kfree(data);
574+
}
575+
out:
576+
spin_unlock_irqrestore(&id_table_lock, flags);
577+
}
578+
448579
static void _cma_attach_to_dev(struct rdma_id_private *id_priv,
449580
struct cma_device *cma_dev)
450581
{
@@ -481,16 +612,6 @@ static void cma_release_dev(struct rdma_id_private *id_priv)
481612
mutex_unlock(&lock);
482613
}
483614

484-
static inline struct sockaddr *cma_src_addr(struct rdma_id_private *id_priv)
485-
{
486-
return (struct sockaddr *) &id_priv->id.route.addr.src_addr;
487-
}
488-
489-
static inline struct sockaddr *cma_dst_addr(struct rdma_id_private *id_priv)
490-
{
491-
return (struct sockaddr *) &id_priv->id.route.addr.dst_addr;
492-
}
493-
494615
static inline unsigned short cma_family(struct rdma_id_private *id_priv)
495616
{
496617
return id_priv->id.route.addr.src_addr.ss_family;
@@ -861,6 +982,7 @@ __rdma_create_id(struct net *net, rdma_cm_event_handler event_handler,
861982
refcount_set(&id_priv->refcount, 1);
862983
mutex_init(&id_priv->handler_mutex);
863984
INIT_LIST_HEAD(&id_priv->device_item);
985+
INIT_LIST_HEAD(&id_priv->id_list_entry);
864986
INIT_LIST_HEAD(&id_priv->listen_list);
865987
INIT_LIST_HEAD(&id_priv->mc_list);
866988
get_random_bytes(&id_priv->seq_num, sizeof id_priv->seq_num);
@@ -1883,6 +2005,7 @@ static void _destroy_id(struct rdma_id_private *id_priv,
18832005
cma_cancel_operation(id_priv, state);
18842006

18852007
rdma_restrack_del(&id_priv->res);
2008+
cma_remove_id_from_tree(id_priv);
18862009
if (id_priv->cma_dev) {
18872010
if (rdma_cap_ib_cm(id_priv->id.device, 1)) {
18882011
if (id_priv->cm_id.ib)
@@ -3172,8 +3295,11 @@ int rdma_resolve_route(struct rdma_cm_id *id, unsigned long timeout_ms)
31723295
cma_id_get(id_priv);
31733296
if (rdma_cap_ib_sa(id->device, id->port_num))
31743297
ret = cma_resolve_ib_route(id_priv, timeout_ms);
3175-
else if (rdma_protocol_roce(id->device, id->port_num))
3298+
else if (rdma_protocol_roce(id->device, id->port_num)) {
31763299
ret = cma_resolve_iboe_route(id_priv);
3300+
if (!ret)
3301+
cma_add_id_to_tree(id_priv);
3302+
}
31773303
else if (rdma_protocol_iwarp(id->device, id->port_num))
31783304
ret = cma_resolve_iw_route(id_priv);
31793305
else
@@ -4922,10 +5048,87 @@ static int cma_netdev_callback(struct notifier_block *self, unsigned long event,
49225048
return ret;
49235049
}
49245050

5051+
static void cma_netevent_work_handler(struct work_struct *_work)
5052+
{
5053+
struct rdma_id_private *id_priv =
5054+
container_of(_work, struct rdma_id_private, id.net_work);
5055+
struct rdma_cm_event event = {};
5056+
5057+
mutex_lock(&id_priv->handler_mutex);
5058+
5059+
if (READ_ONCE(id_priv->state) == RDMA_CM_DESTROYING ||
5060+
READ_ONCE(id_priv->state) == RDMA_CM_DEVICE_REMOVAL)
5061+
goto out_unlock;
5062+
5063+
event.event = RDMA_CM_EVENT_UNREACHABLE;
5064+
event.status = -ETIMEDOUT;
5065+
5066+
if (cma_cm_event_handler(id_priv, &event)) {
5067+
__acquire(&id_priv->handler_mutex);
5068+
id_priv->cm_id.ib = NULL;
5069+
cma_id_put(id_priv);
5070+
destroy_id_handler_unlock(id_priv);
5071+
return;
5072+
}
5073+
5074+
out_unlock:
5075+
mutex_unlock(&id_priv->handler_mutex);
5076+
cma_id_put(id_priv);
5077+
}
5078+
5079+
static int cma_netevent_callback(struct notifier_block *self,
5080+
unsigned long event, void *ctx)
5081+
{
5082+
struct id_table_entry *ips_node = NULL;
5083+
struct rdma_id_private *current_id;
5084+
struct neighbour *neigh = ctx;
5085+
unsigned long flags;
5086+
5087+
if (event != NETEVENT_NEIGH_UPDATE)
5088+
return NOTIFY_DONE;
5089+
5090+
spin_lock_irqsave(&id_table_lock, flags);
5091+
if (neigh->tbl->family == AF_INET6) {
5092+
struct sockaddr_in6 neigh_sock_6;
5093+
5094+
neigh_sock_6.sin6_family = AF_INET6;
5095+
neigh_sock_6.sin6_addr = *(struct in6_addr *)neigh->primary_key;
5096+
ips_node = node_from_ndev_ip(&id_table, neigh->dev->ifindex,
5097+
(struct sockaddr *)&neigh_sock_6);
5098+
} else if (neigh->tbl->family == AF_INET) {
5099+
struct sockaddr_in neigh_sock_4;
5100+
5101+
neigh_sock_4.sin_family = AF_INET;
5102+
neigh_sock_4.sin_addr.s_addr = *(__be32 *)(neigh->primary_key);
5103+
ips_node = node_from_ndev_ip(&id_table, neigh->dev->ifindex,
5104+
(struct sockaddr *)&neigh_sock_4);
5105+
} else
5106+
goto out;
5107+
5108+
if (!ips_node)
5109+
goto out;
5110+
5111+
list_for_each_entry(current_id, &ips_node->id_list, id_list_entry) {
5112+
if (!memcmp(current_id->id.route.addr.dev_addr.dst_dev_addr,
5113+
neigh->ha, ETH_ALEN))
5114+
continue;
5115+
INIT_WORK(&current_id->id.net_work, cma_netevent_work_handler);
5116+
cma_id_get(current_id);
5117+
queue_work(cma_wq, &current_id->id.net_work);
5118+
}
5119+
out:
5120+
spin_unlock_irqrestore(&id_table_lock, flags);
5121+
return NOTIFY_DONE;
5122+
}
5123+
49255124
static struct notifier_block cma_nb = {
49265125
.notifier_call = cma_netdev_callback
49275126
};
49285127

5128+
static struct notifier_block cma_netevent_cb = {
5129+
.notifier_call = cma_netevent_callback
5130+
};
5131+
49295132
static void cma_send_device_removal_put(struct rdma_id_private *id_priv)
49305133
{
49315134
struct rdma_cm_event event = { .event = RDMA_CM_EVENT_DEVICE_REMOVAL };
@@ -5148,6 +5351,7 @@ static int __init cma_init(void)
51485351

51495352
ib_sa_register_client(&sa_client);
51505353
register_netdevice_notifier(&cma_nb);
5354+
register_netevent_notifier(&cma_netevent_cb);
51515355

51525356
ret = ib_register_client(&cma_client);
51535357
if (ret)
@@ -5162,6 +5366,7 @@ static int __init cma_init(void)
51625366
err_ib:
51635367
ib_unregister_client(&cma_client);
51645368
err:
5369+
unregister_netevent_notifier(&cma_netevent_cb);
51655370
unregister_netdevice_notifier(&cma_nb);
51665371
ib_sa_unregister_client(&sa_client);
51675372
unregister_pernet_subsys(&cma_pernet_operations);
@@ -5174,6 +5379,7 @@ static void __exit cma_cleanup(void)
51745379
{
51755380
cma_configfs_exit();
51765381
ib_unregister_client(&cma_client);
5382+
unregister_netevent_notifier(&cma_netevent_cb);
51775383
unregister_netdevice_notifier(&cma_nb);
51785384
ib_sa_unregister_client(&sa_client);
51795385
unregister_pernet_subsys(&cma_pernet_operations);

drivers/infiniband/core/cma_priv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ struct rdma_id_private {
6464
struct list_head listen_item;
6565
struct list_head listen_list;
6666
};
67+
struct list_head id_list_entry;
6768
struct cma_device *cma_dev;
6869
struct list_head mc_list;
6970

drivers/infiniband/core/rdma_core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ static int uverbs_try_lock_object(struct ib_uobject *uobj,
6868
* In exclusive access mode, we check that the counter is zero (nobody
6969
* claimed this object) and we set it to -1. Releasing a shared access
7070
* lock is done simply by decreasing the counter. As for exclusive
71-
* access locks, since only a single one of them is is allowed
71+
* access locks, since only a single one of them is allowed
7272
* concurrently, setting the counter to zero is enough for releasing
7373
* this lock.
7474
*/

0 commit comments

Comments
 (0)