Skip to content

Commit

Permalink
IB/qib: Remove atomic_inc_not_zero() from QP RCU
Browse files Browse the repository at this point in the history
Follow Documentation/RCU/rcuref.txt guidance in removing
atomic_inc_not_zero() from QP RCU implementation.

This patch also removes an unneeded synchronize_rcu() in the add path.

Reviewed-by: Dean Luick <dean.luick@intel.com>
Signed-off-by: Mike Marciniszyn <mike.marciniszyn@intel.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
  • Loading branch information
Mike Marciniszyn authored and Roland Dreier committed Jun 22, 2013
1 parent 8469ba3 commit f7cf9a6
Showing 1 changed file with 15 additions and 14 deletions.
29 changes: 15 additions & 14 deletions drivers/infiniband/hw/qib/qib_qp.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012 Intel Corporation. All rights reserved.
* Copyright (c) 2012, 2013 Intel Corporation. All rights reserved.
* Copyright (c) 2006 - 2012 QLogic Corporation. * All rights reserved.
* Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
*
Expand Down Expand Up @@ -222,8 +222,8 @@ static void insert_qp(struct qib_ibdev *dev, struct qib_qp *qp)
unsigned long flags;
unsigned n = qpn_hash(dev, qp->ibqp.qp_num);

spin_lock_irqsave(&dev->qpt_lock, flags);
atomic_inc(&qp->refcount);
spin_lock_irqsave(&dev->qpt_lock, flags);

if (qp->ibqp.qp_num == 0)
rcu_assign_pointer(ibp->qp0, qp);
Expand All @@ -235,7 +235,6 @@ static void insert_qp(struct qib_ibdev *dev, struct qib_qp *qp)
}

spin_unlock_irqrestore(&dev->qpt_lock, flags);
synchronize_rcu();
}

/*
Expand All @@ -247,36 +246,39 @@ static void remove_qp(struct qib_ibdev *dev, struct qib_qp *qp)
struct qib_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num);
unsigned n = qpn_hash(dev, qp->ibqp.qp_num);
unsigned long flags;
int removed = 1;

spin_lock_irqsave(&dev->qpt_lock, flags);

if (rcu_dereference_protected(ibp->qp0,
lockdep_is_held(&dev->qpt_lock)) == qp) {
atomic_dec(&qp->refcount);
rcu_assign_pointer(ibp->qp0, NULL);
} else if (rcu_dereference_protected(ibp->qp1,
lockdep_is_held(&dev->qpt_lock)) == qp) {
atomic_dec(&qp->refcount);
rcu_assign_pointer(ibp->qp1, NULL);
} else {
struct qib_qp *q;
struct qib_qp __rcu **qpp;

removed = 0;
qpp = &dev->qp_table[n];
for (; (q = rcu_dereference_protected(*qpp,
lockdep_is_held(&dev->qpt_lock))) != NULL;
qpp = &q->next)
if (q == qp) {
atomic_dec(&qp->refcount);
rcu_assign_pointer(*qpp,
rcu_dereference_protected(qp->next,
lockdep_is_held(&dev->qpt_lock)));
removed = 1;
break;
}
}

spin_unlock_irqrestore(&dev->qpt_lock, flags);
synchronize_rcu();
if (removed) {
synchronize_rcu();
atomic_dec(&qp->refcount);
}
}

/**
Expand Down Expand Up @@ -334,26 +336,25 @@ struct qib_qp *qib_lookup_qpn(struct qib_ibport *ibp, u32 qpn)
{
struct qib_qp *qp = NULL;

rcu_read_lock();
if (unlikely(qpn <= 1)) {
rcu_read_lock();
if (qpn == 0)
qp = rcu_dereference(ibp->qp0);
else
qp = rcu_dereference(ibp->qp1);
if (qp)
atomic_inc(&qp->refcount);
} else {
struct qib_ibdev *dev = &ppd_from_ibp(ibp)->dd->verbs_dev;
unsigned n = qpn_hash(dev, qpn);

rcu_read_lock();
for (qp = rcu_dereference(dev->qp_table[n]); qp;
qp = rcu_dereference(qp->next))
if (qp->ibqp.qp_num == qpn)
if (qp->ibqp.qp_num == qpn) {
atomic_inc(&qp->refcount);
break;
}
}
if (qp)
if (unlikely(!atomic_inc_not_zero(&qp->refcount)))
qp = NULL;

rcu_read_unlock();
return qp;
}
Expand Down

0 comments on commit f7cf9a6

Please sign in to comment.