cxgbe(4): Use fcmpset instead of cmpset when appropriate.

Suggested by:	mjg@
MFC after:	1 month
Sponsored by:	Chelsio Communications
This commit is contained in:
Navdeep Parhar 2018-08-23 16:24:27 +00:00
parent ff7b3f731a
commit becda72184
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=338254

View file

@ -122,11 +122,12 @@ drain_ring(struct mp_ring *r, union ring_state os, uint16_t prev, int budget)
n = r->drain(r, cidx, pidx);
if (n == 0) {
critical_enter();
os.state = r->state;
do {
os.state = ns.state = r->state;
ns.state = os.state;
ns.cidx = cidx;
ns.flags = STALLED;
} while (atomic_cmpset_64(&r->state, os.state,
} while (atomic_fcmpset_64(&r->state, &os.state,
ns.state) == 0);
critical_exit();
if (prev != STALLED)
@ -149,11 +150,12 @@ drain_ring(struct mp_ring *r, union ring_state os, uint16_t prev, int budget)
if (cidx != pidx && pending < 64 && total < budget)
continue;
critical_enter();
os.state = r->state;
do {
os.state = ns.state = r->state;
ns.state = os.state;
ns.cidx = cidx;
ns.flags = state_to_flags(ns, total >= budget);
} while (atomic_cmpset_acq_64(&r->state, os.state, ns.state) == 0);
} while (atomic_fcmpset_acq_64(&r->state, &os.state, ns.state) == 0);
critical_exit();
if (ns.flags == ABDICATED)
@ -259,8 +261,8 @@ mp_ring_enqueue(struct mp_ring *r, void **items, int n, int budget)
* Reserve room for the new items. Our reservation, if successful, is
* from 'pidx_start' to 'pidx_stop'.
*/
os.state = r->state;
for (;;) {
os.state = r->state;
if (n >= space_available(r, os)) {
counter_u64_add(r->drops, n);
MPASS(os.flags != IDLE);
@ -271,7 +273,7 @@ mp_ring_enqueue(struct mp_ring *r, void **items, int n, int budget)
ns.state = os.state;
ns.pidx_head = increment_idx(r, os.pidx_head, n);
critical_enter();
if (atomic_cmpset_64(&r->state, os.state, ns.state))
if (atomic_fcmpset_64(&r->state, &os.state, ns.state))
break;
critical_exit();
cpu_spinwait();
@ -301,11 +303,12 @@ mp_ring_enqueue(struct mp_ring *r, void **items, int n, int budget)
* Update the ring's pidx_tail. The release style atomic guarantees
* that the items are visible to any thread that sees the updated pidx.
*/
os.state = r->state;
do {
os.state = ns.state = r->state;
ns.state = os.state;
ns.pidx_tail = pidx_stop;
ns.flags = BUSY;
} while (atomic_cmpset_rel_64(&r->state, os.state, ns.state) == 0);
} while (atomic_fcmpset_rel_64(&r->state, &os.state, ns.state) == 0);
critical_exit();
counter_u64_add(r->enqueues, n);