xfs
[Top] [All Lists]

[PATCH 06/10] repair: fix prefetch queue limiting

To: xfs@xxxxxxxxxxx
Subject: [PATCH 06/10] repair: fix prefetch queue limiting
From: Dave Chinner <david@xxxxxxxxxxxxx>
Date: Thu, 27 Feb 2014 20:51:11 +1100
Delivered-to: xfs@xxxxxxxxxxx
In-reply-to: <1393494675-30194-1-git-send-email-david@xxxxxxxxxxxxx>
References: <1393494675-30194-1-git-send-email-david@xxxxxxxxxxxxx>
From: Dave Chinner <dchinner@xxxxxxxxxx>

The length of the prefetch queue is limited by a semaphore. To avoid
a ABBA deadlock, we only trywait on the semaphore so if we fail to
get it we can kick the IO queues before sleeping. Unfortunately,
the "need to sleep" detection is just a little wrong - it needs to
lok at errno, not err for the EAGAIN value.

Hence this queue throttling has not been working for a long time.

Signed-off-by: Dave Chinner <dchinner@xxxxxxxxxx>
---
 repair/phase6.c   | 9 ++++++++-
 repair/prefetch.c | 2 +-
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/repair/phase6.c b/repair/phase6.c
index 7be68b3..63359d1 100644
--- a/repair/phase6.c
+++ b/repair/phase6.c
@@ -2999,8 +2999,15 @@ traverse_function(
                if (irec->ino_isa_dir == 0)
                        continue;
 
-               if (pf_args)
+               if (pf_args) {
                        sem_post(&pf_args->ra_count);
+#ifdef XR_PF_TRACE
+                       sem_getvalue(&pf_args->ra_count, &i);
+                       pftrace(
+               "processing inode chunk %p in AG %d (sem count = %d)",
+                               irec, agno, i);
+#endif
+               }
 
                for (i = 0; i < XFS_INODES_PER_CHUNK; i++)  {
                        if (inode_isadir(irec, i))
diff --git a/repair/prefetch.c b/repair/prefetch.c
index 984beda..f4f3d71 100644
--- a/repair/prefetch.c
+++ b/repair/prefetch.c
@@ -723,7 +723,7 @@ pf_queuing_worker(
                        irec, args->agno, i);
 #endif
                err = sem_trywait(&args->ra_count);
-               if (err == EAGAIN) {
+               if (err < 0 && errno == EAGAIN) {
                        /*
                         * Kick the queue once we have reached the limit;
                         * without this the threads processing the inodes
-- 
1.8.4.rc3

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