mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-07 17:10:36 +00:00
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:
parent
ff7b3f731a
commit
becda72184
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=338254
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue