xfs: provide a inode iolock lockdep class
The XFS iolock needs to be re-initialised to a new lock class before it enters reclaim to prevent lockdep false positives. Unfortunately, this is not sufficient protection as inodes in the XFS_IRECLAIMABLE state can be recycled and not re-initialised before being reused. We need to re-initialise the lock state when transfering out of XFS_IRECLAIMABLE state to XFS_INEW, but we need to keep the same class as if the inode was just allocated. Hence we need a specific lockdep class variable for the iolock so that both initialisations use the same class. While there, add a specific class for inodes in the reclaim state so that it is easy to tell from lockdep reports what state the inode was in that generated the report. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
Родитель
489a150f64
Коммит
dcfcf20512
|
@ -1118,6 +1118,8 @@ xfs_fs_evict_inode(
|
||||||
*/
|
*/
|
||||||
ASSERT(!rwsem_is_locked(&ip->i_iolock.mr_lock));
|
ASSERT(!rwsem_is_locked(&ip->i_iolock.mr_lock));
|
||||||
mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino);
|
mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino);
|
||||||
|
lockdep_set_class_and_name(&ip->i_iolock.mr_lock,
|
||||||
|
&xfs_iolock_reclaimable, "xfs_iolock_reclaimable");
|
||||||
|
|
||||||
xfs_inactive(ip);
|
xfs_inactive(ip);
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,17 @@
|
||||||
#include "xfs_trace.h"
|
#include "xfs_trace.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define xfs inode iolock lockdep classes. We need to ensure that all active
|
||||||
|
* inodes are considered the same for lockdep purposes, including inodes that
|
||||||
|
* are recycled through the XFS_IRECLAIMABLE state. This is the the only way to
|
||||||
|
* guarantee the locks are considered the same when there are multiple lock
|
||||||
|
* initialisation siteѕ. Also, define a reclaimable inode class so it is
|
||||||
|
* obvious in lockdep reports which class the report is against.
|
||||||
|
*/
|
||||||
|
static struct lock_class_key xfs_iolock_active;
|
||||||
|
struct lock_class_key xfs_iolock_reclaimable;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate and initialise an xfs_inode.
|
* Allocate and initialise an xfs_inode.
|
||||||
*/
|
*/
|
||||||
|
@ -71,6 +82,8 @@ xfs_inode_alloc(
|
||||||
ASSERT(completion_done(&ip->i_flush));
|
ASSERT(completion_done(&ip->i_flush));
|
||||||
|
|
||||||
mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino);
|
mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino);
|
||||||
|
lockdep_set_class_and_name(&ip->i_iolock.mr_lock,
|
||||||
|
&xfs_iolock_active, "xfs_iolock_active");
|
||||||
|
|
||||||
/* initialise the xfs inode */
|
/* initialise the xfs inode */
|
||||||
ip->i_ino = ino;
|
ip->i_ino = ino;
|
||||||
|
@ -218,6 +231,12 @@ xfs_iget_cache_hit(
|
||||||
ip->i_flags |= XFS_INEW;
|
ip->i_flags |= XFS_INEW;
|
||||||
__xfs_inode_clear_reclaim_tag(mp, pag, ip);
|
__xfs_inode_clear_reclaim_tag(mp, pag, ip);
|
||||||
inode->i_state = I_NEW;
|
inode->i_state = I_NEW;
|
||||||
|
|
||||||
|
ASSERT(!rwsem_is_locked(&ip->i_iolock.mr_lock));
|
||||||
|
mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino);
|
||||||
|
lockdep_set_class_and_name(&ip->i_iolock.mr_lock,
|
||||||
|
&xfs_iolock_active, "xfs_iolock_active");
|
||||||
|
|
||||||
spin_unlock(&ip->i_flags_lock);
|
spin_unlock(&ip->i_flags_lock);
|
||||||
write_unlock(&pag->pag_ici_lock);
|
write_unlock(&pag->pag_ici_lock);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -438,6 +438,8 @@ static inline void xfs_ifunlock(xfs_inode_t *ip)
|
||||||
#define XFS_IOLOCK_DEP(flags) (((flags) & XFS_IOLOCK_DEP_MASK) >> XFS_IOLOCK_SHIFT)
|
#define XFS_IOLOCK_DEP(flags) (((flags) & XFS_IOLOCK_DEP_MASK) >> XFS_IOLOCK_SHIFT)
|
||||||
#define XFS_ILOCK_DEP(flags) (((flags) & XFS_ILOCK_DEP_MASK) >> XFS_ILOCK_SHIFT)
|
#define XFS_ILOCK_DEP(flags) (((flags) & XFS_ILOCK_DEP_MASK) >> XFS_ILOCK_SHIFT)
|
||||||
|
|
||||||
|
extern struct lock_class_key xfs_iolock_reclaimable;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Flags for xfs_itruncate_start().
|
* Flags for xfs_itruncate_start().
|
||||||
*/
|
*/
|
||||||
|
|
Загрузка…
Ссылка в новой задаче