aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Wilcox <willy@linux.intel.com>2008-05-19 02:34:27 -0400
committerNiv Sardi <xaiki@debian.org>2008-07-28 02:58:12 -0400
commitd748c62367eb630cc30b91d561a5362f597a0892 (patch)
tree551fc30d6237517822edc6729456349e1bd0ab28
parentd729eae8933cb3eb8edf1446532c178b66b293a9 (diff)
[XFS] Convert l_flushsema to a sv_t
The l_flushsema doesn't exactly have completion semantics, nor mutex semantics. It's used as a list of tasks which are waiting to be notified that a flush has completed. It was also being used in a way that was potentially racy, depending on the semaphore implementation. By using a sv_t instead of a semaphore we avoid the need for a separate counter, since we know we just need to wake everything on the queue. Original waitqueue implementation from Matthew Wilcox. Cleanup and conversion to sv_t by Christoph Hellwig. SGI-PV: 981507 SGI-Modid: xfs-linux-melb:xfs-kern:31059a Signed-off-by: Matthew Wilcox <willy@linux.intel.com> Signed-off-by: Christoph Hellwig <hch@infradead.org> Signed-off-by: David Chinner <dgc@sgi.com> Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
-rw-r--r--fs/xfs/xfs_log.c29
-rw-r--r--fs/xfs/xfs_log_priv.h6
2 files changed, 15 insertions, 20 deletions
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index 6195cc880101..91b00a5686cd 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -1232,7 +1232,7 @@ xlog_alloc_log(xfs_mount_t *mp,
1232 1232
1233 spin_lock_init(&log->l_icloglock); 1233 spin_lock_init(&log->l_icloglock);
1234 spin_lock_init(&log->l_grant_lock); 1234 spin_lock_init(&log->l_grant_lock);
1235 initnsema(&log->l_flushsema, 0, "ic-flush"); 1235 sv_init(&log->l_flush_wait, 0, "flush_wait");
1236 1236
1237 /* log record size must be multiple of BBSIZE; see xlog_rec_header_t */ 1237 /* log record size must be multiple of BBSIZE; see xlog_rec_header_t */
1238 ASSERT((XFS_BUF_SIZE(bp) & BBMASK) == 0); 1238 ASSERT((XFS_BUF_SIZE(bp) & BBMASK) == 0);
@@ -1577,7 +1577,6 @@ xlog_dealloc_log(xlog_t *log)
1577 kmem_free(iclog); 1577 kmem_free(iclog);
1578 iclog = next_iclog; 1578 iclog = next_iclog;
1579 } 1579 }
1580 freesema(&log->l_flushsema);
1581 spinlock_destroy(&log->l_icloglock); 1580 spinlock_destroy(&log->l_icloglock);
1582 spinlock_destroy(&log->l_grant_lock); 1581 spinlock_destroy(&log->l_grant_lock);
1583 1582
@@ -2101,6 +2100,7 @@ xlog_state_do_callback(
2101 int funcdidcallbacks; /* flag: function did callbacks */ 2100 int funcdidcallbacks; /* flag: function did callbacks */
2102 int repeats; /* for issuing console warnings if 2101 int repeats; /* for issuing console warnings if
2103 * looping too many times */ 2102 * looping too many times */
2103 int wake = 0;
2104 2104
2105 spin_lock(&log->l_icloglock); 2105 spin_lock(&log->l_icloglock);
2106 first_iclog = iclog = log->l_iclog; 2106 first_iclog = iclog = log->l_iclog;
@@ -2282,15 +2282,13 @@ xlog_state_do_callback(
2282 } 2282 }
2283#endif 2283#endif
2284 2284
2285 flushcnt = 0; 2285 if (log->l_iclog->ic_state & (XLOG_STATE_ACTIVE|XLOG_STATE_IOERROR))
2286 if (log->l_iclog->ic_state & (XLOG_STATE_ACTIVE|XLOG_STATE_IOERROR)) { 2286 wake = 1;
2287 flushcnt = log->l_flushcnt;
2288 log->l_flushcnt = 0;
2289 }
2290 spin_unlock(&log->l_icloglock); 2287 spin_unlock(&log->l_icloglock);
2291 while (flushcnt--) 2288
2292 vsema(&log->l_flushsema); 2289 if (wake)
2293} /* xlog_state_do_callback */ 2290 sv_broadcast(&log->l_flush_wait);
2291}
2294 2292
2295 2293
2296/* 2294/*
@@ -2388,16 +2386,15 @@ restart:
2388 } 2386 }
2389 2387
2390 iclog = log->l_iclog; 2388 iclog = log->l_iclog;
2391 if (! (iclog->ic_state == XLOG_STATE_ACTIVE)) { 2389 if (iclog->ic_state != XLOG_STATE_ACTIVE) {
2392 log->l_flushcnt++;
2393 spin_unlock(&log->l_icloglock);
2394 xlog_trace_iclog(iclog, XLOG_TRACE_SLEEP_FLUSH); 2390 xlog_trace_iclog(iclog, XLOG_TRACE_SLEEP_FLUSH);
2395 XFS_STATS_INC(xs_log_noiclogs); 2391 XFS_STATS_INC(xs_log_noiclogs);
2396 /* Ensure that log writes happen */ 2392
2397 psema(&log->l_flushsema, PINOD); 2393 /* Wait for log writes to have flushed */
2394 sv_wait(&log->l_flush_wait, 0, &log->l_icloglock, 0);
2398 goto restart; 2395 goto restart;
2399 } 2396 }
2400 ASSERT(iclog->ic_state == XLOG_STATE_ACTIVE); 2397
2401 head = &iclog->ic_header; 2398 head = &iclog->ic_header;
2402 2399
2403 atomic_inc(&iclog->ic_refcnt); /* prevents sync */ 2400 atomic_inc(&iclog->ic_refcnt); /* prevents sync */
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h
index 8952a392b5f3..6245913196b4 100644
--- a/fs/xfs/xfs_log_priv.h
+++ b/fs/xfs/xfs_log_priv.h
@@ -423,10 +423,8 @@ typedef struct log {
423 int l_logBBsize; /* size of log in BB chunks */ 423 int l_logBBsize; /* size of log in BB chunks */
424 424
425 /* The following block of fields are changed while holding icloglock */ 425 /* The following block of fields are changed while holding icloglock */
426 sema_t l_flushsema ____cacheline_aligned_in_smp; 426 sv_t l_flush_wait ____cacheline_aligned_in_smp;
427 /* iclog flushing semaphore */ 427 /* waiting for iclog flush */
428 int l_flushcnt; /* # of procs waiting on this
429 * sema */
430 int l_covered_state;/* state of "covering disk 428 int l_covered_state;/* state of "covering disk
431 * log entries" */ 429 * log entries" */
432 xlog_in_core_t *l_iclog; /* head log queue */ 430 xlog_in_core_t *l_iclog; /* head log queue */