Skip to content

Commit f112a04

Browse files
Dave ChinnerBen Myers
Dave Chinner
authored and
Ben Myers
committed
xfs: lockdep needs to know about 3 dquot-deep nesting
Michael Semon reported that xfs/299 generated this lockdep warning: ============================================= [ INFO: possible recursive locking detected ] 3.12.0-rc2+ #2 Not tainted --------------------------------------------- touch/21072 is trying to acquire lock: (&xfs_dquot_other_class){+.+...}, at: [<c12902fb>] xfs_trans_dqlockedjoin+0x57/0x64 but task is already holding lock: (&xfs_dquot_other_class){+.+...}, at: [<c12902fb>] xfs_trans_dqlockedjoin+0x57/0x64 other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(&xfs_dquot_other_class); lock(&xfs_dquot_other_class); *** DEADLOCK *** May be due to missing lock nesting notation 7 locks held by touch/21072: #0: (sb_writers#10){++++.+}, at: [<c11185b6>] mnt_want_write+0x1e/0x3e #1: (&type->i_mutex_dir_key#4){+.+.+.}, at: [<c11078ee>] do_last+0x245/0xe40 #2: (sb_internal#2){++++.+}, at: [<c122c9e0>] xfs_trans_alloc+0x1f/0x35 #3: (&(&ip->i_lock)->mr_lock/1){+.+...}, at: [<c126cd1b>] xfs_ilock+0x100/0x1f1 #4: (&(&ip->i_lock)->mr_lock){++++-.}, at: [<c126cf52>] xfs_ilock_nowait+0x105/0x22f #5: (&dqp->q_qlock){+.+...}, at: [<c12902fb>] xfs_trans_dqlockedjoin+0x57/0x64 torvalds#6: (&xfs_dquot_other_class){+.+...}, at: [<c12902fb>] xfs_trans_dqlockedjoin+0x57/0x64 The lockdep annotation for dquot lock nesting only understands locking for user and "other" dquots, not user, group and quota dquots. Fix the annotations to match the locking heirarchy we now have. Reported-by: Michael L. Semon <[email protected]> Signed-off-by: Dave Chinner <[email protected]> Reviewed-by: Ben Myers <[email protected]> Signed-off-by: Ben Myers <[email protected]>
1 parent 997def2 commit f112a04

File tree

1 file changed

+16
-3
lines changed

1 file changed

+16
-3
lines changed

fs/xfs/xfs_dquot.c

+16-3
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ int xfs_dqerror_mod = 33;
6464
struct kmem_zone *xfs_qm_dqtrxzone;
6565
static struct kmem_zone *xfs_qm_dqzone;
6666

67-
static struct lock_class_key xfs_dquot_other_class;
67+
static struct lock_class_key xfs_dquot_group_class;
68+
static struct lock_class_key xfs_dquot_project_class;
6869

6970
/*
7071
* This is called to free all the memory associated with a dquot
@@ -703,8 +704,20 @@ xfs_qm_dqread(
703704
* Make sure group quotas have a different lock class than user
704705
* quotas.
705706
*/
706-
if (!(type & XFS_DQ_USER))
707-
lockdep_set_class(&dqp->q_qlock, &xfs_dquot_other_class);
707+
switch (type) {
708+
case XFS_DQ_USER:
709+
/* uses the default lock class */
710+
break;
711+
case XFS_DQ_GROUP:
712+
lockdep_set_class(&dqp->q_qlock, &xfs_dquot_group_class);
713+
break;
714+
case XFS_DQ_PROJ:
715+
lockdep_set_class(&dqp->q_qlock, &xfs_dquot_project_class);
716+
break;
717+
default:
718+
ASSERT(0);
719+
break;
720+
}
708721

709722
XFS_STATS_INC(xs_qm_dquot);
710723

0 commit comments

Comments
 (0)