Commit 671cc8a5 authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet
Browse files

bcachefs: Eliminate memory barrier from fast path of journal_preres_put()

parent 08e33761
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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);
+22 −17
Original line number Diff line number Diff line
@@ -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;

	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;

		if ((flags & JOURNAL_RES_GET_RESERVED) ||
		    new.reserved + d < new.remaining) {
			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)
			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);

	if (ret)
		res->u64s += d;
	return 1;
	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)
+3 −2
Original line number Diff line number Diff line
@@ -105,8 +105,9 @@ union journal_preres_state {
	};

	struct {
		u32		reserved;
		u32		remaining;
		u64		waiting:1,
				reserved:31,
				remaining:32;
	};
};