summaryrefslogtreecommitdiff
path: root/drivers/infiniband/hw/qib/qib_verbs.h
diff options
context:
space:
mode:
authorMike Marciniszyn <mike.marciniszyn@intel.com>2012-06-27 18:33:19 -0400
committerRoland Dreier <roland@purestorage.com>2012-07-08 18:05:19 -0700
commit8aac4cc3a9d7d7c2f203b7a8db521b604cfb5dc9 (patch)
treef9e98f1fd7df79a1577c77d74b7242fa16b9a74d /drivers/infiniband/hw/qib/qib_verbs.h
parent6a82649f217023863d6b1740017e6c3dd6685327 (diff)
IB/qib: RCU locking for MR validation
Profiling indicates that MR validation locking is expensive. The MR table is largely read-only and is a suitable candidate for RCU locking. The patch uses RCU locking during validation to eliminate one lock/unlock during that validation. Reviewed-by: Mike Heinz <michael.william.heinz@intel.com> Signed-off-by: Mike Marciniszyn <mike.marciniszyn@intel.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband/hw/qib/qib_verbs.h')
-rw-r--r--drivers/infiniband/hw/qib/qib_verbs.h7
1 files changed, 5 insertions, 2 deletions
diff --git a/drivers/infiniband/hw/qib/qib_verbs.h b/drivers/infiniband/hw/qib/qib_verbs.h
index 4a2277bc059e..85751fd74371 100644
--- a/drivers/infiniband/hw/qib/qib_verbs.h
+++ b/drivers/infiniband/hw/qib/qib_verbs.h
@@ -303,8 +303,9 @@ struct qib_mregion {
u32 max_segs; /* number of qib_segs in all the arrays */
u32 mapsz; /* size of the map array */
u8 page_shift; /* 0 - non unform/non powerof2 sizes */
- u8 lkey_published; /* in global table */
+ u8 lkey_published; /* in global table */
struct completion comp; /* complete when refcount goes to zero */
+ struct rcu_head list;
atomic_t refcount;
struct qib_segarray *map[0]; /* the segments */
};
@@ -1022,10 +1023,12 @@ static inline void qib_get_mr(struct qib_mregion *mr)
atomic_inc(&mr->refcount);
}
+void mr_rcu_callback(struct rcu_head *list);
+
static inline void qib_put_mr(struct qib_mregion *mr)
{
if (unlikely(atomic_dec_and_test(&mr->refcount)))
- complete(&mr->comp);
+ call_rcu(&mr->list, mr_rcu_callback);
}
static inline void qib_put_ss(struct qib_sge_state *ss)