RDMA fixes for-4.13
Subsystems (3)
Changelog:
v0 -> v1:
* Added Reviewed-by tags
* Moved 10 patches to -next
Thanks
----------------------------------------------------------------
The following changes since commit 5dc78ad1904db597bdb4427f3ead437aae86f54c:
IB/ipoib: Notify on modify QP failure only when relevant (2017-07-23 10:52:00 +0300)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/leon/linux-rdma.git tags/rdma-rc-2017-08-01
for you to fetch changes up to 0626c5a5dec2e601f06a2c03b295fb7d7288e29c:
RDMA/mlx5: Fix existence check for extended address vector (2017-07-31 20:43:06 +0300)
----------------------------------------------------------------
RDMA fixes for 4.13
This patchset contains four patches:
* Two kernel panic fixes from Yishai and Parav.
* The bugfix to mlx5 wrong usage of big-endian variable.
* Preventing leak of reserved field.
----------------------------------------------------------------
Leon Romanovsky (2):
RDMA/uverbs: Prevent leak of reserved field RDMA/mlx5: Fix existence check for extended address vector
Parav Pandit (1):
IB/core: Fix race condition in resolving IP to MAC
Yishai Hadas (1):
IB/uverbs: Fix device cleanup
drivers/infiniband/core/addr.c | 62 +++++++++++++++++++++++++++-------- drivers/infiniband/core/uverbs_cmd.c | 2 +- drivers/infiniband/core/uverbs_main.c | 3 +- drivers/infiniband/hw/mlx5/odp.c | 2 +- include/linux/mlx5/qp.h | 1 - 5 files changed, 51 insertions(+), 19 deletions(-)
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): 20170801064137.8360-1-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org
PATCH 1/4 IB/core: Fix race condition in resolving IP to MAC
From: Parav Pandit <parav-VPRAkNaXOzVWk0Htik3J/[email protected]>
Currently while resolving IP address to MAC address single delayed work is used for resolving multiple such resolve requests. This singled work is essentially performs two tasks.
(a) any retry needed to resolve and
(b) it executes the callback function for all completed requests
While work is executing callbacks, any new work scheduled on for this workqueue is lost because workqueue has completed looking at all pending requests and now looking at callbacks, but work is still under execution. Any further retry to look at pending requests in process_req() after executing callbacks would lead to similar race condition (may be reduce the probably further but doesn't eliminate it). Retrying to enqueue work that from queue_req() context is not something rest of the kernel modules have followed.
Therefore fix in this patch utilizes kernel facility to enqueue multiple work items to a workqueue. This ensures that no such requests gets lost in synchronization. Request list is still maintained so that rdma_cancel_addr() can unlink the request and get the completion with error sooner. Neighbour update event handling continues to be handled in same way as before.
Additionally process_req() work entry cancels any pending work for a request that gets completed while processing those requests.
Originally ib_addr was ST workqueue, but it became MT work queue with patch of [1]. This patch again makes it similar to ST so that neighbour update events handler work item doesn't race with other work items.
In one such below trace, (though on 4.5 based kernel) it can be seen that process_req() never executed the callback, which is likely for an event that was schedule by queue_req() when previous callback was getting executed by workqueue.
[<ffffffff816b0dde>] schedule+0x3e/0x90 [<ffffffff816b3c45>] schedule_timeout+0x1b5/0x210 [<ffffffff81618c37>] ? ip_route_output_flow+0x27/0x70 [<ffffffffa027f9c9>] ? addr_resolve+0x149/0x1b0 [ib_addr] [<ffffffff816b228f>] wait_for_completion+0x10f/0x170 [<ffffffff810b6140>] ? try_to_wake_up+0x210/0x210 [<ffffffffa027f220>] ? rdma_copy_addr+0xa0/0xa0 [ib_addr] [<ffffffffa0280120>] rdma_addr_find_l2_eth_by_grh+0x1d0/0x278 [ib_addr] [<ffffffff81321297>] ? sub_alloc+0x77/0x1c0 [<ffffffffa02943b7>] ib_init_ah_from_wc+0x3a7/0x5a0 [ib_core] [<ffffffffa0457aba>] cm_req_handler+0xea/0x580 [ib_cm] [<ffffffff81015982>] ? __switch_to+0x212/0x5e0 [<ffffffffa04582fd>] cm_work_handler+0x6d/0x150 [ib_cm] [<ffffffff810a14c1>] process_one_work+0x151/0x4b0 [<ffffffff810a1940>] worker_thread+0x120/0x480 [<ffffffff816b074b>] ? __schedule+0x30b/0x890 [<ffffffff810a1820>] ? process_one_work+0x4b0/0x4b0 [<ffffffff810a1820>] ? process_one_work+0x4b0/0x4b0 [<ffffffff810a6b1e>] kthread+0xce/0xf0 [<ffffffff810a6a50>] ? kthread_freezable_should_stop+0x70/0x70 [<ffffffff816b53a2>] ret_from_fork+0x42/0x70 [<ffffffff810a6a50>] ? kthread_freezable_should_stop+0x70/0x70 INFO: task kworker/u144:1:156520 blocked for more than 120 seconds. "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. kworker/u144:1 D ffff883ffe1d7600 0 156520 2 0x00000080 Workqueue: ib_addr process_req [ib_addr] ffff883f446fbbd8 0000000000000046 ffff881f95280000 ffff881ff24de200 ffff883f66120000 ffff883f446f8008 ffff881f95280000 ffff883f6f9208c4 ffff883f6f9208c8 00000000ffffffff ffff883f446fbbf8 ffffffff816b0dde
[1] http://lkml.iu.edu/hypermail/linux/kernel/1608.1/05834.html
--- drivers/infiniband/core/addr.c | 62 ++++++++++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 14 deletions(-)
drivers/infiniband/core/addr.c +48 -14
@@ -61,6 +61,7 @@ struct addr_req {void (*callback)(int status,struct sockaddr *src_addr,struct rdma_dev_addr *addr,void *context);unsigned long timeout; +struct delayed_work work;int status;u32 seq; };
@@ -295,7 +296,7 @@ int rdma_translate_ip(const struct sockaddr *addr, }EXPORT_SYMBOL (rdma_translate_ip); -static void set_timeout (unsigned long time) +static void set_timeout (struct delayed_work *delayed_work,unsigned long time) {unsigned long delay;
@@ -303,7 +304,7 @@ static void set_timeout(unsigned long time)if ((long )delay <0 ) delay =0 ; -mod_delayed_work (addr_wq, &work, delay); +mod_delayed_work (addr_wq, delayed_work, delay); }static void queue_req (struct addr_req *req)
@@ -318,8 +319,7 @@ static void queue_req(struct addr_req *req)list_add (&req->list, &temp_req->list); -if (req_list.next == &req->list) -set_timeout (req->timeout); +set_timeout (&req->work, req->timeout);mutex_unlock (&lock); }
@@ -574,6 +574,37 @@ static int addr_resolve(struct sockaddr *src_in,return ret; } +static void process_one_req (struct work_struct *_work) +{ +struct addr_req *req; +struct sockaddr *src_in, *dst_in; + +mutex_lock (&lock); + req = container_of(_work, struct addr_req, work.work); + +if (req->status == -ENODATA ) { + src_in = (struct sockaddr *)&req->src_addr; + dst_in = (struct sockaddr *)&req->dst_addr; + req->status =addr_resolve (src_in, dst_in, req->addr, + true, req->seq); +if (req->status &&time_after_eq (jiffies, req->timeout)) { + req->status = -ETIMEDOUT ; + }else if (req->status == -ENODATA ) { +/* requeue the work for retrying again */ +set_timeout (&req->work, req->timeout); +mutex_unlock (&lock); +return ; + } + } +list_del (&req->list); +mutex_unlock (&lock); + + req->callback (req->status, (struct sockaddr *)&req->src_addr, + req->addr, req->context); +put_client (req->client); +kfree (req); +} +static void process_req (struct work_struct *work) {struct addr_req *req, *temp_req;
@@ -591,20 +622,23 @@ static void process_req(struct work_struct *work) true, req->seq);if (req->status &&time_after_eq (jiffies, req->timeout)) req->status = -ETIMEDOUT ; -else if (req->status == -ENODATA ) +else if (req->status == -ENODATA ) { +set_timeout (&req->work, req->timeout);continue ; + } }list_move_tail (&req->list, &done_list); } -if (!list_empty (&req_list)) { - req = list_entry(req_list.next, struct addr_req, list); -set_timeout (req->timeout); - }mutex_unlock (&lock);list_for_each_entry_safe (req, temp_req, &done_list, list) {list_del (&req->list); +/* It is safe to cancel other work items from this work item +* because at a time there can be only one work item running +* with this single threaded work queue. +*/ +cancel_delayed_work (&req->work); req->callback (req->status, (struct sockaddr *) &req->src_addr, req->addr, req->context);put_client (req->client);
@@ -647,6 +681,7 @@ int rdma_resolve_ip(struct rdma_addr_client *client, req->context = context; req->client = client;atomic_inc (&client->refcount); +INIT_DELAYED_WORK (&req->work, process_one_req); req->seq = (u32 )atomic_inc_return (&ib_nl_addr_request_seq); req->status =addr_resolve (src_in, dst_in, addr, true, req->seq);
@@ -701,7 +736,7 @@ void rdma_addr_cancel(struct rdma_dev_addr *addr) req->status = -ECANCELED ; req->timeout = jiffies;list_move (&req->list, &req_list); -set_timeout (req->timeout); +set_timeout (&req->work, req->timeout);break ; } }
@@ -807,9 +842,8 @@ static int netevent_callback(struct notifier_block *self, unsigned long event,if (event ==NETEVENT_NEIGH_UPDATE ) {struct neighbour *neigh = ctx; -if (neigh->nud_state &NUD_VALID ) { -set_timeout (jiffies); - } +if (neigh->nud_state &NUD_VALID ) +set_timeout (&work, jiffies); }return 0 ; }
@@ -820,7 +854,7 @@ static struct notifier_block nb = {int addr_init (void ) { - addr_wq =alloc_workqueue ("ib_addr" ,WQ_MEM_RECLAIM ,0 ); + addr_wq =alloc_ordered_workqueue ("ib_addr" ,WQ_MEM_RECLAIM );if (!addr_wq)return -ENOMEM ;
--
2.13.3
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 2/4 RDMA/uverbs: Prevent leak of reserved field
In reply to a message not in the archiveFrom: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/[email protected]>
initialize to zero the response structure to prevent the leakage of "resp.reserved" field.
drivers/infiniband/core/uverbs_cmd.c:1178 ib_uverbs_resize_cq() warn:
check that 'resp.reserved' doesn't leak information
--- drivers/infiniband/core/uverbs_cmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/core/uverbs_cmd.c +1 -1
@@ -1153,7 +1153,7 @@ ssize_t ib_uverbs_resize_cq(struct ib_uverbs_file *file, int out_len) {struct ib_uverbs_resize_cq cmd; -struct ib_uverbs_resize_cq_resp resp; +struct ib_uverbs_resize_cq_resp resp = {};struct ib_udata udata;struct ib_cq *cq;int ret = -EINVAL ;
--
2.13.3
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 3/4 IB/uverbs: Fix device cleanup
In reply to a message not in the archiveFrom: Yishai Hadas <yishaih-VPRAkNaXOzVWk0Htik3J/[email protected]>
Uverbs device should be cleaned up only when there is no potential usage of.
As part of ib_uverbs_remove_one which might be triggered upon reset flow the device reference count is decreased as expected and leave the final cleanup to the FDs that were opened.
Current code increases reference count upon opening a new command FD and decreases it upon closing the file. The event FD is opened internally and rely on the command FD by taking on it a reference count.
In case that the command FD was closed and just later the event FD we may ensure that the device resources as of srcu are still alive as they are still in use.
Fixing the above by moving the reference count decreasing to the place where the command FD is really freed instead of doing that when it was just closed.
--- drivers/infiniband/core/uverbs_main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/infiniband/core/uverbs_main.c +1 -2
@@ -250,6 +250,7 @@ void ib_uverbs_release_file(struct kref *ref)if (atomic_dec_and_test (&file->device->refcount))ib_uverbs_comp_dev (file->device); +kobject_put (&file->device->kobj);kfree (file); }
@@ -917,7 +918,6 @@ static int ib_uverbs_open(struct inode *inode, struct file *filp)static int ib_uverbs_close (struct inode *inode,struct file *filp) {struct ib_uverbs_file *file = filp->private_data; -struct ib_uverbs_device *dev = file->device;mutex_lock (&file->cleanup_mutex);if (file->ucontext) {
@@ -939,7 +939,6 @@ static int ib_uverbs_close(struct inode *inode, struct file *filp) ib_uverbs_release_async_event_file);kref_put (&file->ref, ib_uverbs_release_file); -kobject_put (&dev->kobj);return 0 ; }
--
2.13.3
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 4/4 RDMA/mlx5: Fix existence check for extended address vector
In reply to a message not in the archiveFrom: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/[email protected]>
The extended address vector is the highest bit in be32 variable, but it was compared with the lowest. This patch fixes the endianness of that check and removes already declared define.
--- drivers/infiniband/hw/mlx5/odp.c | 2 +- include/linux/mlx5/qp.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-)
drivers/infiniband/hw/mlx5/odp.c +1 -1
@@ -939,7 +939,7 @@ static int mlx5_ib_mr_initiator_pfault_handler(if (qp->ibqp.qp_type !=IB_QPT_RC ) { av = *wqe; -if (av->dqp_dct &be32_to_cpu (MLX5_WQE_AV_EXT )) +if (av->dqp_dct &cpu_to_be32 (MLX5_EXTENDED_UD_AV )) *wqe +=sizeof (struct mlx5_av );else *wqe +=sizeof (struct mlx5_base_av );
include/linux/mlx5/qp.h +0 -1
@@ -212,7 +212,6 @@ struct mlx5_wqe_ctrl_seg {#define MLX5_WQE_CTRL_OPCODE_MASK 0xff#define MLX5_WQE_CTRL_WQE_INDEX_MASK 0x00ffff00#define MLX5_WQE_CTRL_WQE_INDEX_SHIFT 8 -#define MLX5_WQE_AV_EXT 0x80000000enum {MLX5_ETH_WQE_L3_INNER_CSUM =1 <<4 ,
--
2.13.3
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 33 lines · Leon Romanovsky
Changelog:
v0 -> v1:
* Added Reviewed-by tags
* Moved 10 patches to -nextThanks
----------------------------------------------------------------The following changes since commit
5dc78ad1904db597bdb4427f3ead437aae86f54c:IB/ipoib: Notify on modify QP failure only when relevant (2017-07-
23 10:52:00 +0300)are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/leon/linux-rdma.git
tags/rdma-rc-2017-08-01for you to fetch changes up to
0626c5a5dec2e601f06a2c03b295fb7d7288e29c:RDMA/mlx5: Fix existence check for extended address vector (2017-
07-31 20:43:06 +0300)----------------------------------------------------------------
RDMA fixes for 4.13This patchset contains four patches:
* Two kernel panic fixes from Yishai and Parav.
* The bugfix to mlx5 wrong usage of big-endian variable.
* Preventing leak of reserved field.
Quoted 7 lines
----------------------------------------------------------------
Leon Romanovsky (2):
RDMA/uverbs: Prevent leak of reserved field RDMA/mlx5: Fix existence check for extended address vectorParav Pandit (1):
IB/core: Fix race condition in resolving IP to MAC
This patch, in particular, was very similar in description to another patch I already took for this -rc cycle. Both of these patches ended up using ordered workqueues to resolve the problem. Finding two different workqueues that needed to be made ordered in the same -rc cycle makes me wonder if we might not have some other issues lurking in the subsystem in regards to workqueues...
Quoted 11 lines
Yishai Hadas (1):
IB/uverbs: Fix device cleanupdrivers/infiniband/core/addr.c | 62 +++++++++++++++++++++++++++-------- drivers/infiniband/core/uverbs_cmd.c | 2 +- drivers/infiniband/core/uverbs_main.c | 3 +- drivers/infiniband/hw/mlx5/odp.c | 2 +- include/linux/mlx5/qp.h | 1 - 5 files changed, 51 insertions(+), 19 deletions(-)
I didn't use a pull (mainly because I was going through patchworks and saw the patches and took them from there before I saw the cover letter here with the pull tag...that and I'm not used to the pull request model so hunting through patchworks for the relevant patches is second nature and pull requests aren't). I'll try to keep the pull option in mind next time. In any case, thanks, series applied.
Signature · 8 lines
Doug Ledford <[email protected]> GPG KeyID: B826A3330E572FDD Key fingerprint = AE6B 1BDA 122B 23B4 265B 1274 B826 A333 0E57 2FDD -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 42 lines · Doug Ledford
Quoted 33 lines · Leon Romanovsky
Changelog:
v0 -> v1:
* Added Reviewed-by tags
* Moved 10 patches to -nextThanks
----------------------------------------------------------------The following changes since commit
5dc78ad1904db597bdb4427f3ead437aae86f54c:IB/ipoib: Notify on modify QP failure only when relevant (2017-07-
23 10:52:00 +0300)are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/leon/linux-rdma.git
tags/rdma-rc-2017-08-01for you to fetch changes up to
0626c5a5dec2e601f06a2c03b295fb7d7288e29c:RDMA/mlx5: Fix existence check for extended address vector (2017-
07-31 20:43:06 +0300)----------------------------------------------------------------
RDMA fixes for 4.13This patchset contains four patches:
* Two kernel panic fixes from Yishai and Parav.
* The bugfix to mlx5 wrong usage of big-endian variable.
* Preventing leak of reserved field.Quoted 7 lines
----------------------------------------------------------------
Leon Romanovsky (2):
RDMA/uverbs: Prevent leak of reserved field RDMA/mlx5: Fix existence check for extended address vectorParav Pandit (1):
IB/core: Fix race condition in resolving IP to MAC
Quoted 6 lines
This patch, in particular, was very similar in description to another patch I already took for this -rc cycle. Both of these patches ended up using ordered workqueues to resolve the problem. Finding two different workqueues that needed to be made ordered in the same -rc cycle makes me wonder if we might not have some other issues lurking in the subsystem in regards to workqueues...
I hope no, we don't have many workqueues (except hfi1).
➜ linux-rdma git:(topic/rdma-uapi-export) git grep 'alloc_workqueue(\|create_workqueue(' drivers/infiniband
drivers/infiniband/core/addr.c: addr_wq = alloc_workqueue("ib_addr", WQ_MEM_RECLAIM, 0);
drivers/infiniband/core/cm.c: cm.wq = create_workqueue("ib_cm");
drivers/infiniband/core/device.c: ib_wq = alloc_workqueue("infiniband", 0, 0);
drivers/infiniband/core/device.c: ib_comp_wq = alloc_workqueue("ib-comp-wq",
drivers/infiniband/hw/hfi1/init.c: alloc_workqueue(
drivers/infiniband/hw/usnic/usnic_uiom.c: usnic_uiom_wq = create_workqueue(drv_name);
drivers/infiniband/ulp/iser/iscsi_iser.c: release_wq = alloc_workqueue("release workqueue", 0, 0);
drivers/infiniband/ulp/isert/ib_isert.c: isert_comp_wq = alloc_workqueue("isert_comp_wq",
drivers/infiniband/ulp/isert/ib_isert.c: isert_release_wq = alloc_workqueue("isert_release_wq", WQ_UNBOUND,drivers/infiniband/ulp/srp/ib_srp.c: srp_remove_wq = create_workqueue("srp_remove");
Quoted 25 lines
Quoted 5 lines
Yishai Hadas (1):
IB/uverbs: Fix device cleanupQuoted 7 lines
drivers/infiniband/core/addr.c | 62 +++++++++++++++++++++++++++-------- drivers/infiniband/core/uverbs_cmd.c | 2 +- drivers/infiniband/core/uverbs_main.c | 3 +- drivers/infiniband/hw/mlx5/odp.c | 2 +- include/linux/mlx5/qp.h | 1 - 5 files changed, 51 insertions(+), 19 deletions(-)I didn't use a pull (mainly because I was going through patchworks and saw the patches and took them from there before I saw the cover letter here with the pull tag...that and I'm not used to the pull request model so hunting through patchworks for the relevant patches is second nature and pull requests aren't). I'll try to keep the pull option in mind next time. In any case, thanks, series applied.
--
Doug Ledford <[email protected]>GPG KeyID: B826A3330E572FDD Key fingerprint = AE6B 1BDA 122B 23B4 265B 1274 B826 A333 0E57 2FDD