Skip to content

Commit d1f7256

Browse files
mjguzikbrauner
authored andcommitted
fs: fall back to file_ref_put() for non-last reference
This reduces the slowdown in face of multiple callers issuing close on what turns out to not be the last reference. Signed-off-by: Mateusz Guzik <mjguzik@gmail.com> Link: https://lore.kernel.org/20250418125756.59677-1-mjguzik@gmail.com Reviewed-by: Jan Kara <jack@suse.cz> Reported-by: kernel test robot <oliver.sang@intel.com> Closes: https://lore.kernel.org/oe-lkp/202504171513.6d6f8a16-lkp@intel.com Signed-off-by: Christian Brauner <brauner@kernel.org>
1 parent 53f7eed commit d1f7256

File tree

2 files changed

+7
-14
lines changed

2 files changed

+7
-14
lines changed

fs/file.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
#include "internal.h"
2828

29-
bool __file_ref_put_badval(file_ref_t *ref, unsigned long cnt)
29+
static noinline bool __file_ref_put_badval(file_ref_t *ref, unsigned long cnt)
3030
{
3131
/*
3232
* If the reference count was already in the dead zone, then this

include/linux/file_ref.h

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ static inline void file_ref_init(file_ref_t *ref, unsigned long cnt)
6161
atomic_long_set(&ref->refcnt, cnt - 1);
6262
}
6363

64-
bool __file_ref_put_badval(file_ref_t *ref, unsigned long cnt);
6564
bool __file_ref_put(file_ref_t *ref, unsigned long cnt);
6665

6766
/**
@@ -178,20 +177,14 @@ static __always_inline __must_check bool file_ref_put(file_ref_t *ref)
178177
*/
179178
static __always_inline __must_check bool file_ref_put_close(file_ref_t *ref)
180179
{
181-
long old, new;
180+
long old;
182181

183182
old = atomic_long_read(&ref->refcnt);
184-
do {
185-
if (unlikely(old < 0))
186-
return __file_ref_put_badval(ref, old);
187-
188-
if (old == FILE_REF_ONEREF)
189-
new = FILE_REF_DEAD;
190-
else
191-
new = old - 1;
192-
} while (!atomic_long_try_cmpxchg(&ref->refcnt, &old, new));
193-
194-
return new == FILE_REF_DEAD;
183+
if (likely(old == FILE_REF_ONEREF)) {
184+
if (likely(atomic_long_try_cmpxchg(&ref->refcnt, &old, FILE_REF_DEAD)))
185+
return true;
186+
}
187+
return file_ref_put(ref);
195188
}
196189

197190
/**

0 commit comments

Comments
 (0)