IB/mlx4: Fix race condition between catas error reset and aliasguid flows [Linux 3.16.72]

This Linux kernel change "IB/mlx4: Fix race condition between catas error reset and aliasguid flows" is included in the Linux 3.16.72 release. This change is authored by Jack Morgenstein <jackm [at] dev.mellanox.co.il> on Wed Mar 6 19:17:56 2019 +0200. The commit for this change in Linux stable tree is 507ed21 (patch) which is from upstream commit 587443e. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream 587443e.

IB/mlx4: Fix race condition between catas error reset and aliasguid flows

commit 587443e7773e150ae29e643ee8f41a1eed226565 upstream.

Code review revealed a race condition which could allow the catas error
flow to interrupt the alias guid query post mechanism at random points.
Thiis is fixed by doing cancel_delayed_work_sync() instead of
cancel_delayed_work() during the alias guid mechanism destroy flow.

Fixes: a0c64a17aba8 ("mlx4: Add alias_guid mechanism")
Signed-off-by: Jack Morgenstein <[email protected]>
Signed-off-by: Leon Romanovsky <[email protected]>
Signed-off-by: Jason Gunthorpe <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>

There are 2 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 drivers/infiniband/hw/mlx4/alias_GUID.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/infiniband/hw/mlx4/alias_GUID.c b/drivers/infiniband/hw/mlx4/alias_GUID.c
index 0eb141c..fb60229 100644
--- a/drivers/infiniband/hw/mlx4/alias_GUID.c
+++ b/drivers/infiniband/hw/mlx4/alias_GUID.c
@@ -579,8 +579,8 @@ void mlx4_ib_destroy_alias_guid_service(struct mlx4_ib_dev *dev)
    unsigned long flags;

    for (i = 0 ; i < dev->num_ports; i++) {
-       cancel_delayed_work(&dev->sriov.alias_guid.ports_guid[i].alias_guid_work);
        det = &sriov->alias_guid.ports_guid[i];
+       cancel_delayed_work_sync(&det->alias_guid_work);
        spin_lock_irqsave(&sriov->alias_guid.ag_work_lock, flags);
        while (!list_empty(&det->cb_list)) {
            cb_ctx = list_entry(det->cb_list.next,

Leave a Reply

Your email address will not be published. Required fields are marked *