Commit cbc3d65ebcb0c494183d45cf202a53352cbf3871

Authored by Dave Kleikamp
1 parent de8fd087b2

JFS: Improve sync barrier processing

Under heavy load, hot metadata pages are often locked by non-committed
transactions, making them difficult to flush to disk.  This prevents
the sync point from advancing past a transaction that had modified the
page.

There is a point during the sync barrier processing where all
outstanding transactions have been committed to disk, but no new
transaction have been allowed to proceed.  This is the best time
to write the metadata.

Signed-off-by: Dave Kleikamp <shaggy@austin.ibm.com>

Showing 4 changed files with 26 additions and 24 deletions Side-by-side Diff

... ... @@ -191,7 +191,7 @@
191 191 static bio_end_io_t lbmIODone;
192 192 static void lbmStartIO(struct lbuf * bp);
193 193 static void lmGCwrite(struct jfs_log * log, int cant_block);
194   -static int lmLogSync(struct jfs_log * log, int nosyncwait);
  194 +static int lmLogSync(struct jfs_log * log, int hard_sync);
195 195  
196 196  
197 197  
198 198  
199 199  
... ... @@ -915,19 +915,17 @@
915 915 * if new sync address is available
916 916 * (normally the case if sync() is executed by back-ground
917 917 * process).
918   - * if not, explicitly run jfs_blogsync() to initiate
919   - * getting of new sync address.
920 918 * calculate new value of i_nextsync which determines when
921 919 * this code is called again.
922 920 *
923 921 * PARAMETERS: log - log structure
924   - * nosyncwait - 1 if called asynchronously
  922 + * hard_sync - 1 to force all metadata to be written
925 923 *
926 924 * RETURN: 0
927 925 *
928 926 * serialization: LOG_LOCK() held on entry/exit
929 927 */
930   -static int lmLogSync(struct jfs_log * log, int nosyncwait)
  928 +static int lmLogSync(struct jfs_log * log, int hard_sync)
931 929 {
932 930 int logsize;
933 931 int written; /* written since last syncpt */
... ... @@ -941,11 +939,18 @@
941 939 unsigned long flags;
942 940  
943 941 /* push dirty metapages out to disk */
944   - list_for_each_entry(sbi, &log->sb_list, log_list) {
945   - filemap_flush(sbi->ipbmap->i_mapping);
946   - filemap_flush(sbi->ipimap->i_mapping);
947   - filemap_flush(sbi->direct_inode->i_mapping);
948   - }
  942 + if (hard_sync)
  943 + list_for_each_entry(sbi, &log->sb_list, log_list) {
  944 + filemap_fdatawrite(sbi->ipbmap->i_mapping);
  945 + filemap_fdatawrite(sbi->ipimap->i_mapping);
  946 + filemap_fdatawrite(sbi->direct_inode->i_mapping);
  947 + }
  948 + else
  949 + list_for_each_entry(sbi, &log->sb_list, log_list) {
  950 + filemap_flush(sbi->ipbmap->i_mapping);
  951 + filemap_flush(sbi->ipimap->i_mapping);
  952 + filemap_flush(sbi->direct_inode->i_mapping);
  953 + }
949 954  
950 955 /*
951 956 * forward syncpt
... ... @@ -1021,10 +1026,6 @@
1021 1026 /* next syncpt trigger = written + more */
1022 1027 log->nextsync = written + more;
1023 1028  
1024   - /* return if lmLogSync() from outside of transaction, e.g., sync() */
1025   - if (nosyncwait)
1026   - return lsn;
1027   -
1028 1029 /* if number of bytes written from last sync point is more
1029 1030 * than 1/4 of the log size, stop new transactions from
1030 1031 * starting until all current transactions are completed
1031 1032  
1032 1033  
... ... @@ -1049,11 +1050,12 @@
1049 1050 *
1050 1051 * FUNCTION: write log SYNCPT record for specified log
1051 1052 *
1052   - * PARAMETERS: log - log structure
  1053 + * PARAMETERS: log - log structure
  1054 + * hard_sync - set to 1 to force metadata to be written
1053 1055 */
1054   -void jfs_syncpt(struct jfs_log *log)
  1056 +void jfs_syncpt(struct jfs_log *log, int hard_sync)
1055 1057 { LOG_LOCK(log);
1056   - lmLogSync(log, 1);
  1058 + lmLogSync(log, hard_sync);
1057 1059 LOG_UNLOCK(log);
1058 1060 }
1059 1061  
... ... @@ -510,7 +510,7 @@
510 510 extern int lmGroupCommit(struct jfs_log *, struct tblock *);
511 511 extern int jfsIOWait(void *);
512 512 extern void jfs_flush_journal(struct jfs_log * log, int wait);
513   -extern void jfs_syncpt(struct jfs_log *log);
  513 +extern void jfs_syncpt(struct jfs_log *log, int hard_sync);
514 514  
515 515 #endif /* _H_JFS_LOGMGR */
... ... @@ -552,6 +552,11 @@
552 552 * synchronize with logsync barrier
553 553 */
554 554 if (test_bit(log_SYNCBARRIER, &log->flag)) {
  555 + TXN_UNLOCK();
  556 +
  557 + /* write dirty metadata & forward log syncpt */
  558 + jfs_syncpt(log, 1);
  559 +
555 560 jfs_info("log barrier off: 0x%x", log->lsn);
556 561  
557 562 /* enable new transactions start */
... ... @@ -559,11 +564,6 @@
559 564  
560 565 /* wakeup all waitors for logsync barrier */
561 566 TXN_WAKEUP(&log->syncwait);
562   -
563   - TXN_UNLOCK();
564   -
565   - /* forward log syncpt */
566   - jfs_syncpt(log);
567 567  
568 568 goto wakeup;
569 569 }
... ... @@ -531,7 +531,7 @@
531 531 /* log == NULL indicates read-only mount */
532 532 if (log) {
533 533 jfs_flush_journal(log, wait);
534   - jfs_syncpt(log);
  534 + jfs_syncpt(log, 0);
535 535 }
536 536  
537 537 return 0;