diff options
Diffstat (limited to 'fs/xfs/xfs_log_priv.h')
-rw-r--r-- | fs/xfs/xfs_log_priv.h | 97 |
1 files changed, 59 insertions, 38 deletions
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index e008233ee249..8952a392b5f3 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h | |||
@@ -49,10 +49,10 @@ struct xfs_mount; | |||
49 | #define XLOG_HEADER_SIZE 512 | 49 | #define XLOG_HEADER_SIZE 512 |
50 | 50 | ||
51 | #define XLOG_REC_SHIFT(log) \ | 51 | #define XLOG_REC_SHIFT(log) \ |
52 | BTOBB(1 << (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) ? \ | 52 | BTOBB(1 << (xfs_sb_version_haslogv2(&log->l_mp->m_sb) ? \ |
53 | XLOG_MAX_RECORD_BSHIFT : XLOG_BIG_RECORD_BSHIFT)) | 53 | XLOG_MAX_RECORD_BSHIFT : XLOG_BIG_RECORD_BSHIFT)) |
54 | #define XLOG_TOTAL_REC_SHIFT(log) \ | 54 | #define XLOG_TOTAL_REC_SHIFT(log) \ |
55 | BTOBB(XLOG_MAX_ICLOGS << (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) ? \ | 55 | BTOBB(XLOG_MAX_ICLOGS << (xfs_sb_version_haslogv2(&log->l_mp->m_sb) ? \ |
56 | XLOG_MAX_RECORD_BSHIFT : XLOG_BIG_RECORD_BSHIFT)) | 56 | XLOG_MAX_RECORD_BSHIFT : XLOG_BIG_RECORD_BSHIFT)) |
57 | 57 | ||
58 | 58 | ||
@@ -242,7 +242,7 @@ typedef struct xlog_res { | |||
242 | 242 | ||
243 | typedef struct xlog_ticket { | 243 | typedef struct xlog_ticket { |
244 | sv_t t_sema; /* sleep on this semaphore : 20 */ | 244 | sv_t t_sema; /* sleep on this semaphore : 20 */ |
245 | struct xlog_ticket *t_next; /* :4|8 */ | 245 | struct xlog_ticket *t_next; /* :4|8 */ |
246 | struct xlog_ticket *t_prev; /* :4|8 */ | 246 | struct xlog_ticket *t_prev; /* :4|8 */ |
247 | xlog_tid_t t_tid; /* transaction identifier : 4 */ | 247 | xlog_tid_t t_tid; /* transaction identifier : 4 */ |
248 | int t_curr_res; /* current reservation in bytes : 4 */ | 248 | int t_curr_res; /* current reservation in bytes : 4 */ |
@@ -324,6 +324,19 @@ typedef struct xlog_rec_ext_header { | |||
324 | * - ic_offset is the current number of bytes written to in this iclog. | 324 | * - ic_offset is the current number of bytes written to in this iclog. |
325 | * - ic_refcnt is bumped when someone is writing to the log. | 325 | * - ic_refcnt is bumped when someone is writing to the log. |
326 | * - ic_state is the state of the iclog. | 326 | * - ic_state is the state of the iclog. |
327 | * | ||
328 | * Because of cacheline contention on large machines, we need to separate | ||
329 | * various resources onto different cachelines. To start with, make the | ||
330 | * structure cacheline aligned. The following fields can be contended on | ||
331 | * by independent processes: | ||
332 | * | ||
333 | * - ic_callback_* | ||
334 | * - ic_refcnt | ||
335 | * - fields protected by the global l_icloglock | ||
336 | * | ||
337 | * so we need to ensure that these fields are located in separate cachelines. | ||
338 | * We'll put all the read-only and l_icloglock fields in the first cacheline, | ||
339 | * and move everything else out to subsequent cachelines. | ||
327 | */ | 340 | */ |
328 | typedef struct xlog_iclog_fields { | 341 | typedef struct xlog_iclog_fields { |
329 | sv_t ic_forcesema; | 342 | sv_t ic_forcesema; |
@@ -332,17 +345,22 @@ typedef struct xlog_iclog_fields { | |||
332 | struct xlog_in_core *ic_prev; | 345 | struct xlog_in_core *ic_prev; |
333 | struct xfs_buf *ic_bp; | 346 | struct xfs_buf *ic_bp; |
334 | struct log *ic_log; | 347 | struct log *ic_log; |
335 | xfs_log_callback_t *ic_callback; | ||
336 | xfs_log_callback_t **ic_callback_tail; | ||
337 | #ifdef XFS_LOG_TRACE | ||
338 | struct ktrace *ic_trace; | ||
339 | #endif | ||
340 | int ic_size; | 348 | int ic_size; |
341 | int ic_offset; | 349 | int ic_offset; |
342 | int ic_refcnt; | ||
343 | int ic_bwritecnt; | 350 | int ic_bwritecnt; |
344 | ushort_t ic_state; | 351 | ushort_t ic_state; |
345 | char *ic_datap; /* pointer to iclog data */ | 352 | char *ic_datap; /* pointer to iclog data */ |
353 | #ifdef XFS_LOG_TRACE | ||
354 | struct ktrace *ic_trace; | ||
355 | #endif | ||
356 | |||
357 | /* Callback structures need their own cacheline */ | ||
358 | spinlock_t ic_callback_lock ____cacheline_aligned_in_smp; | ||
359 | xfs_log_callback_t *ic_callback; | ||
360 | xfs_log_callback_t **ic_callback_tail; | ||
361 | |||
362 | /* reference counts need their own cacheline */ | ||
363 | atomic_t ic_refcnt ____cacheline_aligned_in_smp; | ||
346 | } xlog_iclog_fields_t; | 364 | } xlog_iclog_fields_t; |
347 | 365 | ||
348 | typedef union xlog_in_core2 { | 366 | typedef union xlog_in_core2 { |
@@ -366,6 +384,7 @@ typedef struct xlog_in_core { | |||
366 | #define ic_bp hic_fields.ic_bp | 384 | #define ic_bp hic_fields.ic_bp |
367 | #define ic_log hic_fields.ic_log | 385 | #define ic_log hic_fields.ic_log |
368 | #define ic_callback hic_fields.ic_callback | 386 | #define ic_callback hic_fields.ic_callback |
387 | #define ic_callback_lock hic_fields.ic_callback_lock | ||
369 | #define ic_callback_tail hic_fields.ic_callback_tail | 388 | #define ic_callback_tail hic_fields.ic_callback_tail |
370 | #define ic_trace hic_fields.ic_trace | 389 | #define ic_trace hic_fields.ic_trace |
371 | #define ic_size hic_fields.ic_size | 390 | #define ic_size hic_fields.ic_size |
@@ -383,43 +402,46 @@ typedef struct xlog_in_core { | |||
383 | * that round off problems won't occur when releasing partial reservations. | 402 | * that round off problems won't occur when releasing partial reservations. |
384 | */ | 403 | */ |
385 | 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 | |||
386 | /* The following block of fields are changed while holding icloglock */ | 425 | /* The following block of fields are changed while holding icloglock */ |
387 | sema_t l_flushsema; /* iclog flushing semaphore */ | 426 | sema_t l_flushsema ____cacheline_aligned_in_smp; |
427 | /* iclog flushing semaphore */ | ||
388 | int l_flushcnt; /* # of procs waiting on this | 428 | int l_flushcnt; /* # of procs waiting on this |
389 | * sema */ | 429 | * sema */ |
390 | int l_ticket_cnt; /* free ticket count */ | ||
391 | int l_ticket_tcnt; /* total ticket count */ | ||
392 | int l_covered_state;/* state of "covering disk | 430 | int l_covered_state;/* state of "covering disk |
393 | * log entries" */ | 431 | * log entries" */ |
394 | xlog_ticket_t *l_freelist; /* free list of tickets */ | ||
395 | xlog_ticket_t *l_unmount_free;/* kmem_free these addresses */ | ||
396 | xlog_ticket_t *l_tail; /* free list of tickets */ | ||
397 | xlog_in_core_t *l_iclog; /* head log queue */ | 432 | xlog_in_core_t *l_iclog; /* head log queue */ |
398 | spinlock_t l_icloglock; /* grab to change iclog state */ | 433 | spinlock_t l_icloglock; /* grab to change iclog state */ |
399 | 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 |
400 | * buffers */ | 435 | * buffers */ |
401 | 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 */ |
402 | struct xfs_mount *l_mp; /* mount point */ | ||
403 | struct xfs_buf *l_xbuf; /* extra buffer for log | ||
404 | * wrapping */ | ||
405 | struct xfs_buftarg *l_targ; /* buftarg of log */ | ||
406 | xfs_daddr_t l_logBBstart; /* start block of log */ | ||
407 | int l_logsize; /* size of log in bytes */ | ||
408 | int l_logBBsize; /* size of log in BB chunks */ | ||
409 | int l_curr_cycle; /* Cycle number of log writes */ | 437 | int l_curr_cycle; /* Cycle number of log writes */ |
410 | int l_prev_cycle; /* Cycle number before last | 438 | int l_prev_cycle; /* Cycle number before last |
411 | * block increment */ | 439 | * block increment */ |
412 | int l_curr_block; /* current logical log block */ | 440 | int l_curr_block; /* current logical log block */ |
413 | int l_prev_block; /* previous logical log block */ | 441 | int l_prev_block; /* previous logical log block */ |
414 | int l_iclog_size; /* size of log in bytes */ | ||
415 | int l_iclog_size_log; /* log power size of log */ | ||
416 | int l_iclog_bufs; /* number of iclog buffers */ | ||
417 | |||
418 | /* The following field are used for debugging; need to hold icloglock */ | ||
419 | char *l_iclog_bak[XLOG_MAX_ICLOGS]; | ||
420 | 442 | ||
421 | /* The following block of fields are changed while holding grant_lock */ | 443 | /* The following block of fields are changed while holding grant_lock */ |
422 | spinlock_t l_grant_lock; | 444 | spinlock_t l_grant_lock ____cacheline_aligned_in_smp; |
423 | xlog_ticket_t *l_reserve_headq; | 445 | xlog_ticket_t *l_reserve_headq; |
424 | xlog_ticket_t *l_write_headq; | 446 | xlog_ticket_t *l_write_headq; |
425 | int l_grant_reserve_cycle; | 447 | int l_grant_reserve_cycle; |
@@ -427,19 +449,16 @@ typedef struct log { | |||
427 | int l_grant_write_cycle; | 449 | int l_grant_write_cycle; |
428 | int l_grant_write_bytes; | 450 | int l_grant_write_bytes; |
429 | 451 | ||
430 | /* The following fields don't need locking */ | ||
431 | #ifdef XFS_LOG_TRACE | 452 | #ifdef XFS_LOG_TRACE |
432 | struct ktrace *l_trace; | 453 | struct ktrace *l_trace; |
433 | struct ktrace *l_grant_trace; | 454 | struct ktrace *l_grant_trace; |
434 | #endif | 455 | #endif |
435 | uint l_flags; | 456 | |
436 | uint l_quotaoffs_flag; /* XFS_DQ_*, for QUOTAOFFs */ | 457 | /* The following field are used for debugging; need to hold icloglock */ |
437 | struct xfs_buf_cancel **l_buf_cancel_table; | 458 | #ifdef DEBUG |
438 | int l_iclog_hsize; /* size of iclog header */ | 459 | char *l_iclog_bak[XLOG_MAX_ICLOGS]; |
439 | int l_iclog_heads; /* # of iclog header sectors */ | 460 | #endif |
440 | uint l_sectbb_log; /* log2 of sector size in BBs */ | 461 | |
441 | uint l_sectbb_mask; /* sector size (in BBs) | ||
442 | * alignment mask */ | ||
443 | } xlog_t; | 462 | } xlog_t; |
444 | 463 | ||
445 | #define XLOG_FORCED_SHUTDOWN(log) ((log)->l_flags & XLOG_IO_ERROR) | 464 | #define XLOG_FORCED_SHUTDOWN(log) ((log)->l_flags & XLOG_IO_ERROR) |
@@ -459,6 +478,8 @@ extern struct xfs_buf *xlog_get_bp(xlog_t *, int); | |||
459 | extern void xlog_put_bp(struct xfs_buf *); | 478 | extern void xlog_put_bp(struct xfs_buf *); |
460 | extern int xlog_bread(xlog_t *, xfs_daddr_t, int, struct xfs_buf *); | 479 | extern int xlog_bread(xlog_t *, xfs_daddr_t, int, struct xfs_buf *); |
461 | 480 | ||
481 | extern kmem_zone_t *xfs_log_ticket_zone; | ||
482 | |||
462 | /* iclog tracing */ | 483 | /* iclog tracing */ |
463 | #define XLOG_TRACE_GRAB_FLUSH 1 | 484 | #define XLOG_TRACE_GRAB_FLUSH 1 |
464 | #define XLOG_TRACE_REL_FLUSH 2 | 485 | #define XLOG_TRACE_REL_FLUSH 2 |