Browse Source

[XFS] Use KM_NOFS for debug trace buffers

Use KM_NOFS to prevent recursion back into the filesystem which can cause
deadlocks.

In the case of xfs_iread() we hold the lock on the inode cluster buffer
while allocating memory for the trace buffers. If we recurse back into XFS
to flush data that may require a transaction to allocate extents which
needs log space. This can deadlock with the xfsaild thread which can't
push the tail of the log because it is trying to get the inode cluster
buffer lock.

SGI-PV: 981498

SGI-Modid: xfs-linux-melb:xfs-kern:31838a

Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Signed-off-by: David Chinner <david@fromorbit.com>
Lachlan McIlroy 16 năm trước cách đây
mục cha
commit
5695ef46ef

+ 1 - 1
fs/xfs/linux-2.6/xfs_buf.c

@@ -1795,7 +1795,7 @@ int __init
 xfs_buf_init(void)
 xfs_buf_init(void)
 {
 {
 #ifdef XFS_BUF_TRACE
 #ifdef XFS_BUF_TRACE
-	xfs_buf_trace_buf = ktrace_alloc(XFS_BUF_TRACE_SIZE, KM_SLEEP);
+	xfs_buf_trace_buf = ktrace_alloc(XFS_BUF_TRACE_SIZE, KM_NOFS);
 #endif
 #endif
 
 
 	xfs_buf_zone = kmem_zone_init_flags(sizeof(xfs_buf_t), "xfs_buf",
 	xfs_buf_zone = kmem_zone_init_flags(sizeof(xfs_buf_t), "xfs_buf",

+ 1 - 1
fs/xfs/quota/xfs_dquot.c

@@ -112,7 +112,7 @@ xfs_qm_dqinit(
 		complete(&dqp->q_flush);
 		complete(&dqp->q_flush);
 
 
 #ifdef XFS_DQUOT_TRACE
 #ifdef XFS_DQUOT_TRACE
-		dqp->q_trace = ktrace_alloc(DQUOT_TRACE_SIZE, KM_SLEEP);
+		dqp->q_trace = ktrace_alloc(DQUOT_TRACE_SIZE, KM_NOFS);
 		xfs_dqtrace_entry(dqp, "DQINIT");
 		xfs_dqtrace_entry(dqp, "DQINIT");
 #endif
 #endif
 	} else {
 	} else {

+ 1 - 1
fs/xfs/xfs_buf_item.c

@@ -737,7 +737,7 @@ xfs_buf_item_init(
 	bip->bli_format.blf_len = (ushort)BTOBB(XFS_BUF_COUNT(bp));
 	bip->bli_format.blf_len = (ushort)BTOBB(XFS_BUF_COUNT(bp));
 	bip->bli_format.blf_map_size = map_size;
 	bip->bli_format.blf_map_size = map_size;
 #ifdef XFS_BLI_TRACE
 #ifdef XFS_BLI_TRACE
-	bip->bli_trace = ktrace_alloc(XFS_BLI_TRACE_SIZE, KM_SLEEP);
+	bip->bli_trace = ktrace_alloc(XFS_BLI_TRACE_SIZE, KM_NOFS);
 #endif
 #endif
 
 
 #ifdef XFS_TRANS_DEBUG
 #ifdef XFS_TRANS_DEBUG

+ 1 - 1
fs/xfs/xfs_filestream.c

@@ -400,7 +400,7 @@ xfs_filestream_init(void)
 	if (!item_zone)
 	if (!item_zone)
 		return -ENOMEM;
 		return -ENOMEM;
 #ifdef XFS_FILESTREAMS_TRACE
 #ifdef XFS_FILESTREAMS_TRACE
-	xfs_filestreams_trace_buf = ktrace_alloc(XFS_FSTRM_KTRACE_SIZE, KM_SLEEP);
+	xfs_filestreams_trace_buf = ktrace_alloc(XFS_FSTRM_KTRACE_SIZE, KM_NOFS);
 #endif
 #endif
 	return 0;
 	return 0;
 }
 }

+ 6 - 6
fs/xfs/xfs_inode.c

@@ -835,22 +835,22 @@ xfs_iread(
 	 * Do this before xfs_iformat in case it adds entries.
 	 * Do this before xfs_iformat in case it adds entries.
 	 */
 	 */
 #ifdef	XFS_INODE_TRACE
 #ifdef	XFS_INODE_TRACE
-	ip->i_trace = ktrace_alloc(INODE_TRACE_SIZE, KM_SLEEP);
+	ip->i_trace = ktrace_alloc(INODE_TRACE_SIZE, KM_NOFS);
 #endif
 #endif
 #ifdef XFS_BMAP_TRACE
 #ifdef XFS_BMAP_TRACE
-	ip->i_xtrace = ktrace_alloc(XFS_BMAP_KTRACE_SIZE, KM_SLEEP);
+	ip->i_xtrace = ktrace_alloc(XFS_BMAP_KTRACE_SIZE, KM_NOFS);
 #endif
 #endif
 #ifdef XFS_BMBT_TRACE
 #ifdef XFS_BMBT_TRACE
-	ip->i_btrace = ktrace_alloc(XFS_BMBT_KTRACE_SIZE, KM_SLEEP);
+	ip->i_btrace = ktrace_alloc(XFS_BMBT_KTRACE_SIZE, KM_NOFS);
 #endif
 #endif
 #ifdef XFS_RW_TRACE
 #ifdef XFS_RW_TRACE
-	ip->i_rwtrace = ktrace_alloc(XFS_RW_KTRACE_SIZE, KM_SLEEP);
+	ip->i_rwtrace = ktrace_alloc(XFS_RW_KTRACE_SIZE, KM_NOFS);
 #endif
 #endif
 #ifdef XFS_ILOCK_TRACE
 #ifdef XFS_ILOCK_TRACE
-	ip->i_lock_trace = ktrace_alloc(XFS_ILOCK_KTRACE_SIZE, KM_SLEEP);
+	ip->i_lock_trace = ktrace_alloc(XFS_ILOCK_KTRACE_SIZE, KM_NOFS);
 #endif
 #endif
 #ifdef XFS_DIR2_TRACE
 #ifdef XFS_DIR2_TRACE
-	ip->i_dir_trace = ktrace_alloc(XFS_DIR2_KTRACE_SIZE, KM_SLEEP);
+	ip->i_dir_trace = ktrace_alloc(XFS_DIR2_KTRACE_SIZE, KM_NOFS);
 #endif
 #endif
 
 
 	/*
 	/*

+ 1 - 1
fs/xfs/xfs_log.c

@@ -160,7 +160,7 @@ void
 xlog_trace_iclog(xlog_in_core_t *iclog, uint state)
 xlog_trace_iclog(xlog_in_core_t *iclog, uint state)
 {
 {
 	if (!iclog->ic_trace)
 	if (!iclog->ic_trace)
-		iclog->ic_trace = ktrace_alloc(256, KM_SLEEP);
+		iclog->ic_trace = ktrace_alloc(256, KM_NOFS);
 	ktrace_enter(iclog->ic_trace,
 	ktrace_enter(iclog->ic_trace,
 		     (void *)((unsigned long)state),
 		     (void *)((unsigned long)state),
 		     (void *)((unsigned long)current_pid()),
 		     (void *)((unsigned long)current_pid()),