From 7abc664d380e764930270966a91fd19bcae87e3e Mon Sep 17 00:00:00 2001 From: =?utf8?q?H=C3=A5kon=20Bugge?= Date: Fri, 7 Jul 2017 12:33:30 +0200 Subject: [PATCH] net/rds: Add mutex exclusion for vector_load MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Several TOS connections may invoke ibdev_get_unused_vector() concurrently. Hence, mutual exclusion is required to protect rds_ibdev->vector_load. Changes from v1: - Reworded commit message and commentary based on Avinash's feedback - Added r-b from Wei Lin and Avinash Orabug: 26406492 Signed-off-by: HÃ¥kon Bugge Reviewed-by: Wei Lin Guay Reviewed-by: Avinash Repaka --- net/rds/ib.c | 1 + net/rds/ib.h | 4 ++++ net/rds/ib_cm.c | 12 ++++++++++-- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/net/rds/ib.c b/net/rds/ib.c index 93425b800dfb..35dac3bfee74 100644 --- a/net/rds/ib.c +++ b/net/rds/ib.c @@ -2052,6 +2052,7 @@ void rds_ib_add_one(struct ib_device *device) printk(KERN_ERR "RDS/IB: failed to allocate vector memoru\n"); goto put_dev; } + mutex_init(&rds_ibdev->vector_load_lock); rds_ibdev->mr = ib_get_dma_mr(rds_ibdev->pd, IB_ACCESS_LOCAL_WRITE); if (IS_ERR(rds_ibdev->mr)) { diff --git a/net/rds/ib.h b/net/rds/ib.h index fd705edac6a7..f595f358d8d7 100644 --- a/net/rds/ib.h +++ b/net/rds/ib.h @@ -431,6 +431,10 @@ struct rds_ib_device { struct rds_ib_port *ports; struct ib_event_handler event_handler; int *vector_load; + /* Several TOS connections may invoke ibdev_get_unused_vector() + * concurrently, hence we need protection for vector_load + */ + struct mutex vector_load_lock; /* flag indicating ib_device is under freeing up or is freed up to make * the race between rds_ib_remove_one() and rds_release() safe. diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c index a217d978c894..98c14c6e2aa8 100644 --- a/net/rds/ib_cm.c +++ b/net/rds/ib_cm.c @@ -599,10 +599,14 @@ static void rds_ib_qp_event_handler(struct ib_event *event, void *data) static inline int ibdev_get_unused_vector(struct rds_ib_device *rds_ibdev) { - int min = rds_ibdev->vector_load[rds_ibdev->dev->num_comp_vectors - 1]; - int index = rds_ibdev->dev->num_comp_vectors - 1; + int index; + int min; int i; + mutex_lock(&rds_ibdev->vector_load_lock); + min = rds_ibdev->vector_load[rds_ibdev->dev->num_comp_vectors - 1]; + index = rds_ibdev->dev->num_comp_vectors - 1; + for (i = rds_ibdev->dev->num_comp_vectors - 1; i >= 0; i--) { if (rds_ibdev->vector_load[i] < min) { index = i; @@ -611,12 +615,16 @@ static inline int ibdev_get_unused_vector(struct rds_ib_device *rds_ibdev) } rds_ibdev->vector_load[index]++; + mutex_unlock(&rds_ibdev->vector_load_lock); + return index; } static inline void ibdev_put_vector(struct rds_ib_device *rds_ibdev, int index) { + mutex_lock(&rds_ibdev->vector_load_lock); rds_ibdev->vector_load[index]--; + mutex_unlock(&rds_ibdev->vector_load_lock); } /* -- 2.50.1