diff options
author | David Chinner <dgc@sgi.com> | 2008-04-09 22:18:54 -0400 |
---|---|---|
committer | Lachlan McIlroy <lachlan@redback.melbourne.sgi.com> | 2008-04-17 21:50:53 -0400 |
commit | 4679b2d36d53ed508c956337972fbbea8db99a77 (patch) | |
tree | a9b0449c2b0566bb8e8398ff6644def57f7455e3 /fs/xfs | |
parent | eb01c9cd87c7a9998c2edf209721ea069e3e3652 (diff) |
[XFS] Reorganise xlog_t for better cacheline isolation of contention
To reduce contention on the log in large CPU count, separate out different
parts of the xlog_t structure onto different cachelines. Move each lock
onto a different cacheline along with all the members that are
accessed/modified while that lock is held.
Also, move the debugging code into debug code.
SGI-PV: 978729
SGI-Modid: xfs-linux-melb:xfs-kern:30772a
Signed-off-by: David Chinner <dgc@sgi.com>
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/xfs_log.c | 5 | ||||
-rw-r--r-- | fs/xfs/xfs_log_priv.h | 55 |
2 files changed, 32 insertions, 28 deletions
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 3cf115d8de75..319b98eb410c 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -1237,9 +1237,9 @@ xlog_alloc_log(xfs_mount_t *mp, | |||
1237 | XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)1); | 1237 | XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)1); |
1238 | iclog->ic_bp = bp; | 1238 | iclog->ic_bp = bp; |
1239 | iclog->hic_data = bp->b_addr; | 1239 | iclog->hic_data = bp->b_addr; |
1240 | 1240 | #ifdef DEBUG | |
1241 | log->l_iclog_bak[i] = (xfs_caddr_t)&(iclog->ic_header); | 1241 | log->l_iclog_bak[i] = (xfs_caddr_t)&(iclog->ic_header); |
1242 | 1242 | #endif | |
1243 | head = &iclog->ic_header; | 1243 | head = &iclog->ic_header; |
1244 | memset(head, 0, sizeof(xlog_rec_header_t)); | 1244 | memset(head, 0, sizeof(xlog_rec_header_t)); |
1245 | head->h_magicno = cpu_to_be32(XLOG_HEADER_MAGIC_NUM); | 1245 | head->h_magicno = cpu_to_be32(XLOG_HEADER_MAGIC_NUM); |
@@ -1250,7 +1250,6 @@ xlog_alloc_log(xfs_mount_t *mp, | |||
1250 | head->h_fmt = cpu_to_be32(XLOG_FMT); | 1250 | head->h_fmt = cpu_to_be32(XLOG_FMT); |
1251 | memcpy(&head->h_fs_uuid, &mp->m_sb.sb_uuid, sizeof(uuid_t)); | 1251 | memcpy(&head->h_fs_uuid, &mp->m_sb.sb_uuid, sizeof(uuid_t)); |
1252 | 1252 | ||
1253 | |||
1254 | iclog->ic_size = XFS_BUF_SIZE(bp) - log->l_iclog_hsize; | 1253 | iclog->ic_size = XFS_BUF_SIZE(bp) - log->l_iclog_hsize; |
1255 | iclog->ic_state = XLOG_STATE_ACTIVE; | 1254 | iclog->ic_state = XLOG_STATE_ACTIVE; |
1256 | iclog->ic_log = log; | 1255 | iclog->ic_log = log; |
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index c1583960009d..8952a392b5f3 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h | |||
@@ -361,7 +361,7 @@ typedef struct xlog_iclog_fields { | |||
361 | 361 | ||
362 | /* reference counts need their own cacheline */ | 362 | /* reference counts need their own cacheline */ |
363 | atomic_t ic_refcnt ____cacheline_aligned_in_smp; | 363 | atomic_t ic_refcnt ____cacheline_aligned_in_smp; |
364 | } xlog_iclog_fields_t ____cacheline_aligned_in_smp; | 364 | } xlog_iclog_fields_t; |
365 | 365 | ||
366 | typedef union xlog_in_core2 { | 366 | typedef union xlog_in_core2 { |
367 | xlog_rec_header_t hic_header; | 367 | xlog_rec_header_t hic_header; |
@@ -402,8 +402,29 @@ typedef struct xlog_in_core { | |||
402 | * that round off problems won't occur when releasing partial reservations. | 402 | * that round off problems won't occur when releasing partial reservations. |
403 | */ | 403 | */ |
404 | typedef struct log { | 404 | typedef struct log { |
405 | /* The following fields don't need locking */ | ||
406 | struct xfs_mount *l_mp; /* mount point */ | ||
407 | struct xfs_buf *l_xbuf; /* extra buffer for log | ||
408 | * wrapping */ | ||
409 | struct xfs_buftarg *l_targ; /* buftarg of log */ | ||
410 | uint l_flags; | ||
411 | uint l_quotaoffs_flag; /* XFS_DQ_*, for QUOTAOFFs */ | ||
412 | struct xfs_buf_cancel **l_buf_cancel_table; | ||
413 | int l_iclog_hsize; /* size of iclog header */ | ||
414 | int l_iclog_heads; /* # of iclog header sectors */ | ||
415 | uint l_sectbb_log; /* log2 of sector size in BBs */ | ||
416 | uint l_sectbb_mask; /* sector size (in BBs) | ||
417 | * alignment mask */ | ||
418 | int l_iclog_size; /* size of log in bytes */ | ||
419 | int l_iclog_size_log; /* log power size of log */ | ||
420 | int l_iclog_bufs; /* number of iclog buffers */ | ||
421 | xfs_daddr_t l_logBBstart; /* start block of log */ | ||
422 | int l_logsize; /* size of log in bytes */ | ||
423 | int l_logBBsize; /* size of log in BB chunks */ | ||
424 | |||
405 | /* The following block of fields are changed while holding icloglock */ | 425 | /* The following block of fields are changed while holding icloglock */ |
406 | sema_t l_flushsema; /* iclog flushing semaphore */ | 426 | sema_t l_flushsema ____cacheline_aligned_in_smp; |
427 | /* iclog flushing semaphore */ | ||
407 | int l_flushcnt; /* # of procs waiting on this | 428 | int l_flushcnt; /* # of procs waiting on this |
408 | * sema */ | 429 | * sema */ |
409 | int l_covered_state;/* state of "covering disk | 430 | int l_covered_state;/* state of "covering disk |
@@ -413,27 +434,14 @@ typedef struct log { | |||
413 | xfs_lsn_t l_tail_lsn; /* lsn of 1st LR with unflushed | 434 | xfs_lsn_t l_tail_lsn; /* lsn of 1st LR with unflushed |
414 | * buffers */ | 435 | * buffers */ |
415 | xfs_lsn_t l_last_sync_lsn;/* lsn of last LR on disk */ | 436 | xfs_lsn_t l_last_sync_lsn;/* lsn of last LR on disk */ |
416 | struct xfs_mount *l_mp; /* mount point */ | ||
417 | struct xfs_buf *l_xbuf; /* extra buffer for log | ||
418 | * wrapping */ | ||
419 | struct xfs_buftarg *l_targ; /* buftarg of log */ | ||
420 | xfs_daddr_t l_logBBstart; /* start block of log */ | ||
421 | int l_logsize; /* size of log in bytes */ | ||
422 | int l_logBBsize; /* size of log in BB chunks */ | ||
423 | int l_curr_cycle; /* Cycle number of log writes */ | 437 | int l_curr_cycle; /* Cycle number of log writes */ |
424 | int l_prev_cycle; /* Cycle number before last | 438 | int l_prev_cycle; /* Cycle number before last |
425 | * block increment */ | 439 | * block increment */ |
426 | int l_curr_block; /* current logical log block */ | 440 | int l_curr_block; /* current logical log block */ |
427 | int l_prev_block; /* previous logical log block */ | 441 | int l_prev_block; /* previous logical log block */ |
428 | int l_iclog_size; /* size of log in bytes */ | ||
429 | int l_iclog_size_log; /* log power size of log */ | ||
430 | int l_iclog_bufs; /* number of iclog buffers */ | ||
431 | |||
432 | /* The following field are used for debugging; need to hold icloglock */ | ||
433 | char *l_iclog_bak[XLOG_MAX_ICLOGS]; | ||
434 | 442 | ||
435 | /* The following block of fields are changed while holding grant_lock */ | 443 | /* The following block of fields are changed while holding grant_lock */ |
436 | spinlock_t l_grant_lock; | 444 | spinlock_t l_grant_lock ____cacheline_aligned_in_smp; |
437 | xlog_ticket_t *l_reserve_headq; | 445 | xlog_ticket_t *l_reserve_headq; |
438 | xlog_ticket_t *l_write_headq; | 446 | xlog_ticket_t *l_write_headq; |
439 | int l_grant_reserve_cycle; | 447 | int l_grant_reserve_cycle; |
@@ -441,19 +449,16 @@ typedef struct log { | |||
441 | int l_grant_write_cycle; | 449 | int l_grant_write_cycle; |
442 | int l_grant_write_bytes; | 450 | int l_grant_write_bytes; |
443 | 451 | ||
444 | /* The following fields don't need locking */ | ||
445 | #ifdef XFS_LOG_TRACE | 452 | #ifdef XFS_LOG_TRACE |
446 | struct ktrace *l_trace; | 453 | struct ktrace *l_trace; |
447 | struct ktrace *l_grant_trace; | 454 | struct ktrace *l_grant_trace; |
448 | #endif | 455 | #endif |
449 | uint l_flags; | 456 | |
450 | uint l_quotaoffs_flag; /* XFS_DQ_*, for QUOTAOFFs */ | 457 | /* The following field are used for debugging; need to hold icloglock */ |
451 | struct xfs_buf_cancel **l_buf_cancel_table; | 458 | #ifdef DEBUG |
452 | int l_iclog_hsize; /* size of iclog header */ | 459 | char *l_iclog_bak[XLOG_MAX_ICLOGS]; |
453 | int l_iclog_heads; /* # of iclog header sectors */ | 460 | #endif |
454 | uint l_sectbb_log; /* log2 of sector size in BBs */ | 461 | |
455 | uint l_sectbb_mask; /* sector size (in BBs) | ||
456 | * alignment mask */ | ||
457 | } xlog_t; | 462 | } xlog_t; |
458 | 463 | ||
459 | #define XLOG_FORCED_SHUTDOWN(log) ((log)->l_flags & XLOG_IO_ERROR) | 464 | #define XLOG_FORCED_SHUTDOWN(log) ((log)->l_flags & XLOG_IO_ERROR) |