From: Håkon Bugge Date: Fri, 7 Jul 2017 10:33:30 +0000 (+0200) Subject: net/rds: Add mutex exclusion for vector_load X-Git-Tag: v4.1.12-106.0.20170710_2300~15 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=7abc664d380e764930270966a91fd19bcae87e3e;p=users%2Fjedix%2Flinux-maple.git net/rds: Add mutex exclusion for vector_load 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 --- 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); } /*