bcachefs: Eliminate memory barrier from fast path of journal_preres_put()
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
08e337618f
commit
671cc8a51b
@ -520,7 +520,7 @@ static bool journal_preres_available(struct journal *j,
|
||||
unsigned new_u64s,
|
||||
unsigned flags)
|
||||
{
|
||||
bool ret = bch2_journal_preres_get_fast(j, res, new_u64s, flags);
|
||||
bool ret = bch2_journal_preres_get_fast(j, res, new_u64s, flags, true);
|
||||
|
||||
if (!ret && mutex_trylock(&j->reclaim_lock)) {
|
||||
bch2_journal_reclaim(j);
|
||||
|
@ -411,7 +411,12 @@ static inline void bch2_journal_preres_put(struct journal *j,
|
||||
|
||||
s.v = atomic64_sub_return(s.v, &j->prereserved.counter);
|
||||
res->u64s = 0;
|
||||
closure_wake_up(&j->preres_wait);
|
||||
|
||||
if (unlikely(s.waiting)) {
|
||||
clear_bit(ilog2((((union journal_preres_state) { .waiting = 1 }).v)),
|
||||
(unsigned long *) &j->prereserved.v);
|
||||
closure_wake_up(&j->preres_wait);
|
||||
}
|
||||
|
||||
if (s.reserved <= s.remaining &&
|
||||
!test_bit(JOURNAL_MAY_GET_UNRESERVED, &j->flags)) {
|
||||
@ -427,32 +432,32 @@ int __bch2_journal_preres_get(struct journal *,
|
||||
static inline int bch2_journal_preres_get_fast(struct journal *j,
|
||||
struct journal_preres *res,
|
||||
unsigned new_u64s,
|
||||
unsigned flags)
|
||||
unsigned flags,
|
||||
bool set_waiting)
|
||||
{
|
||||
int d = new_u64s - res->u64s;
|
||||
union journal_preres_state old, new;
|
||||
u64 v = atomic64_read(&j->prereserved.counter);
|
||||
int ret;
|
||||
|
||||
do {
|
||||
old.v = new.v = v;
|
||||
ret = 0;
|
||||
|
||||
new.reserved += d;
|
||||
|
||||
/*
|
||||
* If we're being called from the journal reclaim path, we have
|
||||
* to unconditionally give out the pre-reservation, there's
|
||||
* nothing else sensible we can do - otherwise we'd recurse back
|
||||
* into the reclaim path and deadlock:
|
||||
*/
|
||||
|
||||
if (!(flags & JOURNAL_RES_GET_RESERVED) &&
|
||||
new.reserved > new.remaining)
|
||||
if ((flags & JOURNAL_RES_GET_RESERVED) ||
|
||||
new.reserved + d < new.remaining) {
|
||||
new.reserved += d;
|
||||
ret = 1;
|
||||
} else if (set_waiting && !new.waiting)
|
||||
new.waiting = true;
|
||||
else
|
||||
return 0;
|
||||
} while ((v = atomic64_cmpxchg(&j->prereserved.counter,
|
||||
old.v, new.v)) != old.v);
|
||||
|
||||
res->u64s += d;
|
||||
return 1;
|
||||
if (ret)
|
||||
res->u64s += d;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int bch2_journal_preres_get(struct journal *j,
|
||||
@ -463,7 +468,7 @@ static inline int bch2_journal_preres_get(struct journal *j,
|
||||
if (new_u64s <= res->u64s)
|
||||
return 0;
|
||||
|
||||
if (bch2_journal_preres_get_fast(j, res, new_u64s, flags))
|
||||
if (bch2_journal_preres_get_fast(j, res, new_u64s, flags, false))
|
||||
return 0;
|
||||
|
||||
if (flags & JOURNAL_RES_GET_NONBLOCK)
|
||||
|
@ -105,8 +105,9 @@ union journal_preres_state {
|
||||
};
|
||||
|
||||
struct {
|
||||
u32 reserved;
|
||||
u32 remaining;
|
||||
u64 waiting:1,
|
||||
reserved:31,
|
||||
remaining:32;
|
||||
};
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user