[openib-general] qp lock in mthca_poll_cq
Michael S. Tsirkin
mst at mellanox.co.il
Sun Aug 15 05:50:27 PDT 2004
Hello, Roland!
Thanks, the comment in mthca_provider.h clarified things to me.
A couple of small things I'd like to remark on:
Quoting r. Roland Dreier (roland at topspin.com) "Re: [openib-general] qp lock in mthca_poll_cq":
> There are two separate uses of the QP during CQ poll, which is why
> refcount is an atomic_t and we also take the spinlock.
>
> First, the refcount is used to make sure that destroy_qp does not
> get rid of the QP struct while the QP is being accessed to handle
> poll_cq.
Wouldnt locking the cq while QP is being destroyed also work?
And maybe the eq which gets the async events.
> It is an atomic_t because it may be accessed without the QP
> lock being held (eg when an async event is received for the QP).
I see. Maybe this code:
spin_lock(&dev->qp_table.lock);
qp = mthca_array_get(&dev->qp_table.qp, qpn & (dev->limits.num_qps - 1));
if (qp)
atomic_inc(&qp->refcount);
spin_unlock(&dev->qp_table.lock);
and this
if (atomic_dec_and_test(&qp->refcount))
wake_up(&qp->wait);
Shall be factored in inline functions?
There appear to be several users of such constructs
in mthca_cq and mthca_qp.
Something like mthca_qp_get / mthca_qp_put.
>
> Second, the QP's lock is taken during CQE processing because other
> non-atomic parts of the QP struct such as the number of WQEs
> outstanding _are_ modified and need to be protected against concurrent
> access from the send/receive post routine.
>
> It might be possible to avoid taking the QP lock in poll_cq by making
> the current WQE count an atomic_t, but I'm not sure if that's a win
> because it means that send/receive posting would have to use atomic
> accesses as well (and I don't think you can make posting WQEs lock-free).
It seems so, since one has to serialize the access to the queue itself.
> Some of my reasoning is in the comment near the bottom of
> mthca_provider.h too.
It says there:
* We have one global lock that protects dev->cq/qp_table. Each
* struct mthca_cq/qp also has its own lock. No locks should be
* nested inside each other.
However mthca_poll_one takes qp->lock while cq->lock is being held
in mthca_poll_cq.
Isn't that nesting?
> - Roland
MST
More information about the general
mailing list