Skip to content

Commit a1cdde8

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 has been a quiet cycle for RDMA, the big bulk is the usual smallish driver updates and bug fixes. About four new uAPI related things. Not as much Szykaller patches this time, the bugs it finds are getting harder to fix. Summary: - More work cleaning up the RDMA CM code - Usual driver bug fixes and cleanups for qedr, qib, hfi1, hns, i40iw, iw_cxgb4, mlx5, rxe - Driver specific resource tracking and reporting via netlink - Continued work for name space support from Parav - MPLS support for the verbs flow steering uAPI - A few tricky IPoIB fixes improving robustness - HFI1 driver support for the '16B' management packet format - Some auditing to not print kernel pointers via %llx or similar - Mark the entire 'UCM' user-space interface as BROKEN with the intent to remove it entirely. The user space side of this was long ago replaced with RDMA-CM and syzkaller is finding bugs in the residual UCM interface nobody wishes to fix because nobody uses it. - Purge more bogus BUG_ON's from Leon - 'flow counters' verbs uAPI - T10 fixups for iser/isert, these are Acked by Martin but going through the RDMA tree due to dependencies" * tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: (138 commits) RDMA/mlx5: Update SPDX tags to show proper license RDMA/restrack: Change SPDX tag to properly reflect license IB/hfi1: Fix comment on default hdr entry size IB/hfi1: Rename exp_lock to exp_mutex IB/hfi1: Add bypass register defines and replace blind constants IB/hfi1: Remove unused variable IB/hfi1: Ensure VL index is within bounds IB/hfi1: Fix user context tail allocation for DMA_RTAIL IB/hns: Use zeroing memory allocator instead of allocator/memset infiniband: fix a possible use-after-free bug iw_cxgb4: add INFINIBAND_ADDR_TRANS dependency IB/isert: use T10-PI check mask definitions from core layer IB/iser: use T10-PI check mask definitions from core layer RDMA/core: introduce check masks for T10-PI offload IB/isert: fix T10-pi check mask setting IB/mlx5: Add counters read support IB/mlx5: Add flow counters read support IB/mlx5: Add flow counters binding support IB/mlx5: Add counters create and destroy support IB/uverbs: Add support for flow counters ...
2 parents 3a3869f + c1191a1 commit a1cdde8

File tree

144 files changed

+4471
-1783
lines changed

Some content is hidden

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

144 files changed

+4471
-1783
lines changed

drivers/infiniband/Kconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,17 @@ config INFINIBAND_USER_ACCESS
3535
libibverbs, libibcm and a hardware driver library from
3636
rdma-core <https://github.com/linux-rdma/rdma-core>.
3737

38+
config INFINIBAND_USER_ACCESS_UCM
39+
bool "Userspace CM (UCM, DEPRECATED)"
40+
depends on BROKEN
41+
depends on INFINIBAND_USER_ACCESS
42+
help
43+
The UCM module has known security flaws, which no one is
44+
interested to fix. The user-space part of this code was
45+
dropped from the upstream a long time ago.
46+
47+
This option is DEPRECATED and planned to be removed.
48+
3849
config INFINIBAND_EXP_LEGACY_VERBS_NEW_UAPI
3950
bool "Allow experimental legacy verbs in new ioctl uAPI (EXPERIMENTAL)"
4051
depends on INFINIBAND_USER_ACCESS

drivers/infiniband/core/Makefile

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,16 @@ user_access-$(CONFIG_INFINIBAND_ADDR_TRANS) := rdma_ucm.o
55
obj-$(CONFIG_INFINIBAND) += ib_core.o ib_cm.o iw_cm.o \
66
$(infiniband-y)
77
obj-$(CONFIG_INFINIBAND_USER_MAD) += ib_umad.o
8-
obj-$(CONFIG_INFINIBAND_USER_ACCESS) += ib_uverbs.o ib_ucm.o \
9-
$(user_access-y)
8+
obj-$(CONFIG_INFINIBAND_USER_ACCESS) += ib_uverbs.o $(user_access-y)
9+
obj-$(CONFIG_INFINIBAND_USER_ACCESS_UCM) += ib_ucm.o $(user_access-y)
1010

1111
ib_core-y := packer.o ud_header.o verbs.o cq.o rw.o sysfs.o \
1212
device.o fmr_pool.o cache.o netlink.o \
1313
roce_gid_mgmt.o mr_pool.o addr.o sa_query.o \
1414
multicast.o mad.o smi.o agent.o mad_rmpp.o \
15-
security.o nldev.o restrack.o
15+
nldev.o restrack.o
1616

17+
ib_core-$(CONFIG_SECURITY_INFINIBAND) += security.o
1718
ib_core-$(CONFIG_INFINIBAND_USER_MEM) += umem.o
1819
ib_core-$(CONFIG_INFINIBAND_ON_DEMAND_PAGING) += umem_odp.o
1920
ib_core-$(CONFIG_CGROUP_RDMA) += cgroup.o
@@ -36,4 +37,4 @@ ib_uverbs-y := uverbs_main.o uverbs_cmd.o uverbs_marshall.o \
3637
rdma_core.o uverbs_std_types.o uverbs_ioctl.o \
3738
uverbs_ioctl_merge.o uverbs_std_types_cq.o \
3839
uverbs_std_types_flow_action.o uverbs_std_types_dm.o \
39-
uverbs_std_types_mr.o
40+
uverbs_std_types_mr.o uverbs_std_types_counters.o

drivers/infiniband/core/addr.c

Lines changed: 59 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ struct addr_req {
5656
struct sockaddr_storage src_addr;
5757
struct sockaddr_storage dst_addr;
5858
struct rdma_dev_addr *addr;
59-
struct rdma_addr_client *client;
6059
void *context;
6160
void (*callback)(int status, struct sockaddr *src_addr,
6261
struct rdma_dev_addr *addr, void *context);
@@ -68,11 +67,8 @@ struct addr_req {
6867

6968
static atomic_t ib_nl_addr_request_seq = ATOMIC_INIT(0);
7069

71-
static void process_req(struct work_struct *work);
72-
73-
static DEFINE_MUTEX(lock);
70+
static DEFINE_SPINLOCK(lock);
7471
static LIST_HEAD(req_list);
75-
static DECLARE_DELAYED_WORK(work, process_req);
7672
static struct workqueue_struct *addr_wq;
7773

7874
static const struct nla_policy ib_nl_addr_policy[LS_NLA_TYPE_MAX] = {
@@ -112,7 +108,7 @@ static void ib_nl_process_good_ip_rsep(const struct nlmsghdr *nlh)
112108
memcpy(&gid, nla_data(curr), nla_len(curr));
113109
}
114110

115-
mutex_lock(&lock);
111+
spin_lock_bh(&lock);
116112
list_for_each_entry(req, &req_list, list) {
117113
if (nlh->nlmsg_seq != req->seq)
118114
continue;
@@ -122,7 +118,7 @@ static void ib_nl_process_good_ip_rsep(const struct nlmsghdr *nlh)
122118
found = 1;
123119
break;
124120
}
125-
mutex_unlock(&lock);
121+
spin_unlock_bh(&lock);
126122

127123
if (!found)
128124
pr_info("Couldn't find request waiting for DGID: %pI6\n",
@@ -223,28 +219,6 @@ int rdma_addr_size_kss(struct __kernel_sockaddr_storage *addr)
223219
}
224220
EXPORT_SYMBOL(rdma_addr_size_kss);
225221

226-
static struct rdma_addr_client self;
227-
228-
void rdma_addr_register_client(struct rdma_addr_client *client)
229-
{
230-
atomic_set(&client->refcount, 1);
231-
init_completion(&client->comp);
232-
}
233-
EXPORT_SYMBOL(rdma_addr_register_client);
234-
235-
static inline void put_client(struct rdma_addr_client *client)
236-
{
237-
if (atomic_dec_and_test(&client->refcount))
238-
complete(&client->comp);
239-
}
240-
241-
void rdma_addr_unregister_client(struct rdma_addr_client *client)
242-
{
243-
put_client(client);
244-
wait_for_completion(&client->comp);
245-
}
246-
EXPORT_SYMBOL(rdma_addr_unregister_client);
247-
248222
void rdma_copy_addr(struct rdma_dev_addr *dev_addr,
249223
const struct net_device *dev,
250224
const unsigned char *dst_dev_addr)
@@ -302,31 +276,23 @@ int rdma_translate_ip(const struct sockaddr *addr,
302276
}
303277
EXPORT_SYMBOL(rdma_translate_ip);
304278

305-
static void set_timeout(struct delayed_work *delayed_work, unsigned long time)
279+
static void set_timeout(struct addr_req *req, unsigned long time)
306280
{
307281
unsigned long delay;
308282

309283
delay = time - jiffies;
310284
if ((long)delay < 0)
311285
delay = 0;
312286

313-
mod_delayed_work(addr_wq, delayed_work, delay);
287+
mod_delayed_work(addr_wq, &req->work, delay);
314288
}
315289

316290
static void queue_req(struct addr_req *req)
317291
{
318-
struct addr_req *temp_req;
319-
320-
mutex_lock(&lock);
321-
list_for_each_entry_reverse(temp_req, &req_list, list) {
322-
if (time_after_eq(req->timeout, temp_req->timeout))
323-
break;
324-
}
325-
326-
list_add(&req->list, &temp_req->list);
327-
328-
set_timeout(&req->work, req->timeout);
329-
mutex_unlock(&lock);
292+
spin_lock_bh(&lock);
293+
list_add_tail(&req->list, &req_list);
294+
set_timeout(req, req->timeout);
295+
spin_unlock_bh(&lock);
330296
}
331297

332298
static int ib_nl_fetch_ha(const struct dst_entry *dst,
@@ -584,7 +550,6 @@ static void process_one_req(struct work_struct *_work)
584550
struct addr_req *req;
585551
struct sockaddr *src_in, *dst_in;
586552

587-
mutex_lock(&lock);
588553
req = container_of(_work, struct addr_req, work.work);
589554

590555
if (req->status == -ENODATA) {
@@ -596,72 +561,33 @@ static void process_one_req(struct work_struct *_work)
596561
req->status = -ETIMEDOUT;
597562
} else if (req->status == -ENODATA) {
598563
/* requeue the work for retrying again */
599-
set_timeout(&req->work, req->timeout);
600-
mutex_unlock(&lock);
564+
spin_lock_bh(&lock);
565+
if (!list_empty(&req->list))
566+
set_timeout(req, req->timeout);
567+
spin_unlock_bh(&lock);
601568
return;
602569
}
603570
}
604-
list_del(&req->list);
605-
mutex_unlock(&lock);
606-
607-
/*
608-
* Although the work will normally have been canceled by the
609-
* workqueue, it can still be requeued as long as it is on the
610-
* req_list, so it could have been requeued before we grabbed &lock.
611-
* We need to cancel it after it is removed from req_list to really be
612-
* sure it is safe to free.
613-
*/
614-
cancel_delayed_work(&req->work);
615571

616572
req->callback(req->status, (struct sockaddr *)&req->src_addr,
617573
req->addr, req->context);
618-
put_client(req->client);
619-
kfree(req);
620-
}
621-
622-
static void process_req(struct work_struct *work)
623-
{
624-
struct addr_req *req, *temp_req;
625-
struct sockaddr *src_in, *dst_in;
626-
struct list_head done_list;
627-
628-
INIT_LIST_HEAD(&done_list);
629-
630-
mutex_lock(&lock);
631-
list_for_each_entry_safe(req, temp_req, &req_list, list) {
632-
if (req->status == -ENODATA) {
633-
src_in = (struct sockaddr *) &req->src_addr;
634-
dst_in = (struct sockaddr *) &req->dst_addr;
635-
req->status = addr_resolve(src_in, dst_in, req->addr,
636-
true, req->seq);
637-
if (req->status && time_after_eq(jiffies, req->timeout))
638-
req->status = -ETIMEDOUT;
639-
else if (req->status == -ENODATA) {
640-
set_timeout(&req->work, req->timeout);
641-
continue;
642-
}
643-
}
644-
list_move_tail(&req->list, &done_list);
645-
}
646-
647-
mutex_unlock(&lock);
648-
649-
list_for_each_entry_safe(req, temp_req, &done_list, list) {
650-
list_del(&req->list);
651-
/* It is safe to cancel other work items from this work item
652-
* because at a time there can be only one work item running
653-
* with this single threaded work queue.
574+
req->callback = NULL;
575+
576+
spin_lock_bh(&lock);
577+
if (!list_empty(&req->list)) {
578+
/*
579+
* Although the work will normally have been canceled by the
580+
* workqueue, it can still be requeued as long as it is on the
581+
* req_list.
654582
*/
655583
cancel_delayed_work(&req->work);
656-
req->callback(req->status, (struct sockaddr *) &req->src_addr,
657-
req->addr, req->context);
658-
put_client(req->client);
584+
list_del_init(&req->list);
659585
kfree(req);
660586
}
587+
spin_unlock_bh(&lock);
661588
}
662589

663-
int rdma_resolve_ip(struct rdma_addr_client *client,
664-
struct sockaddr *src_addr, struct sockaddr *dst_addr,
590+
int rdma_resolve_ip(struct sockaddr *src_addr, struct sockaddr *dst_addr,
665591
struct rdma_dev_addr *addr, int timeout_ms,
666592
void (*callback)(int status, struct sockaddr *src_addr,
667593
struct rdma_dev_addr *addr, void *context),
@@ -693,8 +619,6 @@ int rdma_resolve_ip(struct rdma_addr_client *client,
693619
req->addr = addr;
694620
req->callback = callback;
695621
req->context = context;
696-
req->client = client;
697-
atomic_inc(&client->refcount);
698622
INIT_DELAYED_WORK(&req->work, process_one_req);
699623
req->seq = (u32)atomic_inc_return(&ib_nl_addr_request_seq);
700624

@@ -710,7 +634,6 @@ int rdma_resolve_ip(struct rdma_addr_client *client,
710634
break;
711635
default:
712636
ret = req->status;
713-
atomic_dec(&client->refcount);
714637
goto err;
715638
}
716639
return ret;
@@ -742,18 +665,36 @@ int rdma_resolve_ip_route(struct sockaddr *src_addr,
742665
void rdma_addr_cancel(struct rdma_dev_addr *addr)
743666
{
744667
struct addr_req *req, *temp_req;
668+
struct addr_req *found = NULL;
745669

746-
mutex_lock(&lock);
670+
spin_lock_bh(&lock);
747671
list_for_each_entry_safe(req, temp_req, &req_list, list) {
748672
if (req->addr == addr) {
749-
req->status = -ECANCELED;
750-
req->timeout = jiffies;
751-
list_move(&req->list, &req_list);
752-
set_timeout(&req->work, req->timeout);
673+
/*
674+
* Removing from the list means we take ownership of
675+
* the req
676+
*/
677+
list_del_init(&req->list);
678+
found = req;
753679
break;
754680
}
755681
}
756-
mutex_unlock(&lock);
682+
spin_unlock_bh(&lock);
683+
684+
if (!found)
685+
return;
686+
687+
/*
688+
* sync canceling the work after removing it from the req_list
689+
* guarentees no work is running and none will be started.
690+
*/
691+
cancel_delayed_work_sync(&found->work);
692+
693+
if (found->callback)
694+
found->callback(-ECANCELED, (struct sockaddr *)&found->src_addr,
695+
found->addr, found->context);
696+
697+
kfree(found);
757698
}
758699
EXPORT_SYMBOL(rdma_addr_cancel);
759700

@@ -791,8 +732,8 @@ int rdma_addr_find_l2_eth_by_grh(const union ib_gid *sgid,
791732
dev_addr.net = &init_net;
792733

793734
init_completion(&ctx.comp);
794-
ret = rdma_resolve_ip(&self, &sgid_addr._sockaddr, &dgid_addr._sockaddr,
795-
&dev_addr, 1000, resolve_cb, &ctx);
735+
ret = rdma_resolve_ip(&sgid_addr._sockaddr, &dgid_addr._sockaddr,
736+
&dev_addr, 1000, resolve_cb, &ctx);
796737
if (ret)
797738
return ret;
798739

@@ -810,11 +751,17 @@ int rdma_addr_find_l2_eth_by_grh(const union ib_gid *sgid,
810751
static int netevent_callback(struct notifier_block *self, unsigned long event,
811752
void *ctx)
812753
{
754+
struct addr_req *req;
755+
813756
if (event == NETEVENT_NEIGH_UPDATE) {
814757
struct neighbour *neigh = ctx;
815758

816-
if (neigh->nud_state & NUD_VALID)
817-
set_timeout(&work, jiffies);
759+
if (neigh->nud_state & NUD_VALID) {
760+
spin_lock_bh(&lock);
761+
list_for_each_entry(req, &req_list, list)
762+
set_timeout(req, jiffies);
763+
spin_unlock_bh(&lock);
764+
}
818765
}
819766
return 0;
820767
}
@@ -830,14 +777,13 @@ int addr_init(void)
830777
return -ENOMEM;
831778

832779
register_netevent_notifier(&nb);
833-
rdma_addr_register_client(&self);
834780

835781
return 0;
836782
}
837783

838784
void addr_cleanup(void)
839785
{
840-
rdma_addr_unregister_client(&self);
841786
unregister_netevent_notifier(&nb);
842787
destroy_workqueue(addr_wq);
788+
WARN_ON(!list_empty(&req_list));
843789
}

0 commit comments

Comments
 (0)