xfs
[Top] [All Lists]

Re: [PATCH 1/9] xfs: avoid memory allocation under m_peraglock in growfs

To: Christoph Hellwig <hch@xxxxxxxxxxxxx>
Subject: Re: [PATCH 1/9] xfs: avoid memory allocation under m_peraglock in growfs code
From: Felix Blyakher <felixb@xxxxxxx>
Date: Sun, 26 Jul 2009 20:48:07 -0500
Cc: xfs@xxxxxxxxxxx, sage@xxxxxxxxxxxx
In-reply-to: <20090718221732.034903000@xxxxxxxxxxxxxxxxxxxxxx>
References: <20090718221452.594956000@xxxxxxxxxxxxxxxxxxxxxx> <20090718221732.034903000@xxxxxxxxxxxxxxxxxxxxxx>

On Jul 18, 2009, at 5:14 PM, Christoph Hellwig wrote:

Allocate the memory for the larger m_perag array before taking the
per-AG lock as the per-AG lock can be taken under the i_lock which
can be taken from reclaim context.

Reported by the new reclaim context tracing in lockdep.

Signed-off-by: Christoph Hellwig <hch@xxxxxx>

For the whole series:

Reviewed-by: Felix Blyakher <felixb@xxxxxxx>



Index: linux-2.6/fs/xfs/xfs_fsops.c
===================================================================
--- linux-2.6.orig/fs/xfs/xfs_fsops.c 2009-07-10 13:05:24.798364926 +0200
+++ linux-2.6/fs/xfs/xfs_fsops.c        2009-07-10 13:16:00.827394975 +0200
@@ -167,17 +167,25 @@ xfs_growfs_data_private(
        new = nb - mp->m_sb.sb_dblocks;
        oagcount = mp->m_sb.sb_agcount;
        if (nagcount > oagcount) {
+               void *new_perag, *old_perag;
+
                xfs_filestream_flush(mp);
+
+               new_perag = kmem_zalloc(sizeof(xfs_perag_t) * nagcount,
+                                       KM_MAYFAIL);
+               if (!new_perag)
+                       return XFS_ERROR(ENOMEM);
+
                down_write(&mp->m_peraglock);
-               mp->m_perag = kmem_realloc(mp->m_perag,
-                       sizeof(xfs_perag_t) * nagcount,
-                       sizeof(xfs_perag_t) * oagcount,
-                       KM_SLEEP);
-               memset(&mp->m_perag[oagcount], 0,
-                       (nagcount - oagcount) * sizeof(xfs_perag_t));
+               memcpy(new_perag, mp->m_perag, sizeof(xfs_perag_t) * oagcount);
+               old_perag = mp->m_perag;
+               mp->m_perag = new_perag;
+
                mp->m_flags |= XFS_MOUNT_32BITINODES;
                nagimax = xfs_initialize_perag(mp, nagcount);
                up_write(&mp->m_peraglock);
+
+               kmem_free(old_perag);
        }
        tp = xfs_trans_alloc(mp, XFS_TRANS_GROWFS);
        tp->t_flags |= XFS_TRANS_RESERVE;

_______________________________________________
xfs mailing list
xfs@xxxxxxxxxxx
http://oss.sgi.com/mailman/listinfo/xfs

<Prev in Thread] Current Thread [Next in Thread>