FROMGIT: f2fs: Restore rwsem lockdep support

Lockdep uses lock class keys in its analysis. init_rwsem() instantiates
one lock class key with each init_rwsem() user as follows:

 #define init_rwsem(sem)                                        \
 do {                                                           \
         static struct lock_class_key __key;                    \
                                                                \
         __init_rwsem((sem), #sem, &__key);                     \
 } while (0)

Commit e4544b63a7ee ("f2fs: move f2fs to use reader-unfair rwsems") reduced
the number of lock class keys from one per init_rwsem() user to one per
file in which init_f2fs_rwsem() is used. This causes the same lock class key
to be associated with multiple f2fs rwsems and also triggers a number of
false positive lockdep deadlock reports. Fix this by again instantiating one
lock class key with each init_f2fs_rwsem() caller.

Bug: 223346410
Cc: Tim Murray <timmurray@google.com>
Reported-by: syzbot+0b9cadf5fc45a98a5083@syzkaller.appspotmail.com
Fixes: e4544b63a7ee ("f2fs: move f2fs to use reader-unfair rwsems")
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
(cherry picked from commit c7f91bd4102902384137dd5c50d04bfed27050dd
 git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git dev)
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Change-Id: I7ece9c98db2e84e54427a2c8155043cb15223ba3
This commit is contained in:
Bart Van Assche
2022-02-22 10:43:13 -08:00
committed by Jaegeuk Kim
parent 4cc8ec84be
commit 91fef75d48

View File

@@ -2080,9 +2080,17 @@ static inline bool enabled_nat_bits(struct f2fs_sb_info *sbi,
return (cpc) ? (cpc->reason & CP_UMOUNT) && set : set; return (cpc) ? (cpc->reason & CP_UMOUNT) && set : set;
} }
static inline void init_f2fs_rwsem(struct f2fs_rwsem *sem) #define init_f2fs_rwsem(sem) \
do { \
static struct lock_class_key __key; \
\
__init_f2fs_rwsem((sem), #sem, &__key); \
} while (0)
static inline void __init_f2fs_rwsem(struct f2fs_rwsem *sem,
const char *sem_name, struct lock_class_key *key)
{ {
init_rwsem(&sem->internal_rwsem); __init_rwsem(&sem->internal_rwsem, sem_name, key);
init_waitqueue_head(&sem->read_waiters); init_waitqueue_head(&sem->read_waiters);
} }