xfs
[Top] [All Lists]

[PATCH 07/12] repair: fix another ABBA deadlock in inode prefetching

To: xfs@xxxxxxxxxxx
Subject: [PATCH 07/12] repair: fix another ABBA deadlock in inode prefetching
From: Christoph Hellwig <hch@xxxxxxxxxxxxx>
Date: Fri, 02 Dec 2011 12:46:26 -0500
References: <20111202174619.179530033@xxxxxxxxxxxxxxxxxxxxxx>
User-agent: quilt/0.48-1
The inode prefetching code has a fixed limit of inodes that might are
submitted at a time.  Unfortunately the buffers for them get locked
once the prefetching starts.  That way the threads processing the inode
might get stuck on buffer locked, but not submitted for reading yet.

Fix this by kicking the queue as soon as we would have to wait on the
ra_count semaphore.

Reported-by: Arkadiusz Mi??kiewicz <arekm@xxxxxxxx>
Tested-by: Arkadiusz Mi??kiewicz <arekm@xxxxxxxx>
Signed-off-by: Christoph Hellwig <hch@xxxxxx>

Index: xfsprogs-dev/repair/prefetch.c
===================================================================
--- xfsprogs-dev.orig/repair/prefetch.c 2011-11-25 13:46:47.195999430 +0100
+++ xfsprogs-dev/repair/prefetch.c      2011-11-25 13:50:41.264731371 +0100
@@ -641,7 +641,18 @@ pf_queuing_worker(
                pftrace("queuing irec %p in AG %d, sem count = %d",
                        irec, args->agno, i);
 #endif
-               sem_wait(&args->ra_count);
+               err = sem_trywait(&args->ra_count);
+               if (err == EAGAIN) {
+                       /*
+                        * Kick the queue once we have reached the limit;
+                        * without this the threads processing the inodes
+                        * might get stuck on a buffer that has been locked
+                        * and added to the I/O queue but is waiting for
+                        * the thread to be woken.
+                        */
+                       pf_start_io_workers(args);
+                       sem_wait(&args->ra_count);
+               }
 
                num_inos = 0;
                bno = XFS_AGINO_TO_AGBNO(mp, cur_irec->ino_startnum);

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