| @@ -1075,6 +1075,32 @@ out: · 1074 unmodified lines |
| 1075 | return ret; | 1075 | return ret; |
| 1076 | } | 1076 | } |
| 1077 | | 1077 | |
| | 1078 | static void ext4_fc_update_stats(struct super_block *sb, int status, |
| | 1079 | u64 commit_time, int nblks) |
| | 1080 | { |
| | 1081 | struct ext4_fc_stats *stats = &EXT4_SB(sb)->s_fc_stats; |
| | 1082 | |
| | 1083 | jbd_debug(1, "Fast commit ended with status = %d", status); |
| | 1084 | if (status == EXT4_FC_STATUS_OK) { |
| | 1085 | stats->fc_num_commits++; |
| | 1086 | stats->fc_numblks += nblks; |
| | 1087 | if (likely(stats->s_fc_avg_commit_time)) |
| | 1088 | stats->s_fc_avg_commit_time = |
| | 1089 | (commit_time + |
| | 1090 | stats->s_fc_avg_commit_time * 3) / 4; |
| | 1091 | else |
| | 1092 | stats->s_fc_avg_commit_time = commit_time; |
| | 1093 | } else if (status == EXT4_FC_STATUS_FAILED || |
| | 1094 | status == EXT4_FC_STATUS_INELIGIBLE) { |
| | 1095 | if (status == EXT4_FC_STATUS_FAILED) |
| | 1096 | stats->fc_failed_commits++; |
| | 1097 | stats->fc_ineligible_commits++; |
| | 1098 | } else { |
| | 1099 | stats->fc_skipped_commits++; |
| | 1100 | } |
| | 1101 | trace_ext4_fc_commit_stop(sb, nblks, status); |
| | 1102 | } |
| | 1103 | |
| 1078 | /* | 1104 | /* |
| 1079 | * The main commit entry point. Performs a fast commit for transaction | 1105 | * The main commit entry point. Performs a fast commit for transaction |
| 1080 | * commit_tid if needed. If it's not possible to perform a fast commit | 1106 | * commit_tid if needed. If it's not possible to perform a fast commit |
| @@ -1087,7 +1113,7 @@ int ext4_fc_commit(journal_t *journal, tid_t commit_tid) · 6 unmodified lines |
| 1087 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 1113 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
| 1088 | int nblks = 0, ret, bsize = journal->j_blocksize; | 1114 | int nblks = 0, ret, bsize = journal->j_blocksize; |
| 1089 | int subtid = atomic_read(&sbi->s_fc_subtid); | 1115 | int subtid = atomic_read(&sbi->s_fc_subtid); |
| 1090 | int reason = EXT4_FC_REASON_OK, fc_bufs_before = 0; | 1116 | int status = EXT4_FC_STATUS_OK, fc_bufs_before = 0; |
| 1091 | ktime_t start_time, commit_time; | 1117 | ktime_t start_time, commit_time; |
| 1092 | | 1118 | |
| 1093 | trace_ext4_fc_commit_start(sb); | 1119 | trace_ext4_fc_commit_start(sb); |
| @@ -1104,69 +1130,52 @@ restart_fc: · 10 unmodified lines |
| 1104 | if (atomic_read(&sbi->s_fc_subtid) <= subtid && | 1130 | if (atomic_read(&sbi->s_fc_subtid) <= subtid && |
| 1105 | commit_tid > journal->j_commit_sequence) | 1131 | commit_tid > journal->j_commit_sequence) |
| 1106 | goto restart_fc; | 1132 | goto restart_fc; |
| 1107 | reason = EXT4_FC_REASON_ALREADY_COMMITTED; | 1133 | ext4_fc_update_stats(sb, EXT4_FC_STATUS_SKIPPED, 0, 0); |
| 1108 | goto out; | 1134 | return 0; |
| 1109 | } else if (ret) { | 1135 | } else if (ret) { |
| 1110 | sbi->s_fc_stats.fc_ineligible_reason_count[EXT4_FC_COMMIT_FAILED]++; | 1136 | /* |
| 1111 | reason = EXT4_FC_REASON_FC_START_FAILED; | 1137 | * Commit couldn't start. Just update stats and perform a |
| 1112 | goto out; | 1138 | * full commit. |
| | 1139 | */ |
| | 1140 | ext4_fc_update_stats(sb, EXT4_FC_STATUS_FAILED, 0, 0); |
| | 1141 | return jbd2_complete_transaction(journal, commit_tid); |
| 1113 | } | 1142 | } |
| | 1143 | |
| 1114 | /* | 1144 | /* |
| 1115 | * After establishing journal barrier via jbd2_fc_begin_commit(), check | 1145 | * After establishing journal barrier via jbd2_fc_begin_commit(), check |
| 1116 | * if we are fast commit ineligible. | 1146 | * if we are fast commit ineligible. |
| 1117 | */ | 1147 | */ |
| 1118 | if (ext4_test_mount_flag(sb, EXT4_MF_FC_INELIGIBLE)) { | 1148 | if (ext4_test_mount_flag(sb, EXT4_MF_FC_INELIGIBLE)) { |
| 1119 | reason = EXT4_FC_REASON_INELIGIBLE; | 1149 | status = EXT4_FC_STATUS_INELIGIBLE; |
| 1120 | goto out; | 1150 | goto fallback; |
| 1121 | } | 1151 | } |
| 1122 | | 1152 | |
| 1123 | fc_bufs_before = (sbi->s_fc_bytes + bsize - 1) / bsize; | 1153 | fc_bufs_before = (sbi->s_fc_bytes + bsize - 1) / bsize; |
| 1124 | ret = ext4_fc_perform_commit(journal); | 1154 | ret = ext4_fc_perform_commit(journal); |
| 1125 | if (ret < 0) { | 1155 | if (ret < 0) { |
| 1126 | sbi->s_fc_stats.fc_ineligible_reason_count[EXT4_FC_COMMIT_FAILED]++; | 1156 | status = EXT4_FC_STATUS_FAILED; |
| 1127 | reason = EXT4_FC_REASON_FC_FAILED; | 1157 | goto fallback; |
| 1128 | goto out; | | |
| 1129 | } | 1158 | } |
| 1130 | nblks = (sbi->s_fc_bytes + bsize - 1) / bsize - fc_bufs_before; | 1159 | nblks = (sbi->s_fc_bytes + bsize - 1) / bsize - fc_bufs_before; |
| 1131 | ret = jbd2_fc_wait_bufs(journal, nblks); | 1160 | ret = jbd2_fc_wait_bufs(journal, nblks); |
| 1132 | if (ret < 0) { | 1161 | if (ret < 0) { |
| 1133 | sbi->s_fc_stats.fc_ineligible_reason_count[EXT4_FC_COMMIT_FAILED]++; | 1162 | status = EXT4_FC_STATUS_FAILED; |
| 1134 | reason = EXT4_FC_REASON_FC_FAILED; | 1163 | goto fallback; |
| 1135 | goto out; | | |
| 1136 | } | 1164 | } |
| 1137 | atomic_inc(&sbi->s_fc_subtid); | 1165 | atomic_inc(&sbi->s_fc_subtid); |
| 1138 | jbd2_fc_end_commit(journal); | 1166 | ret = jbd2_fc_end_commit(journal); |
| 1139 | out: | | |
| 1140 | spin_lock(&sbi->s_fc_lock); | | |
| 1141 | if (reason != EXT4_FC_REASON_OK && | | |
| 1142 | reason != EXT4_FC_REASON_ALREADY_COMMITTED) { | | |
| 1143 | sbi->s_fc_stats.fc_ineligible_commits++; | | |
| 1144 | } else { | | |
| 1145 | sbi->s_fc_stats.fc_num_commits++; | | |
| 1146 | sbi->s_fc_stats.fc_numblks += nblks; | | |
| 1147 | } | | |
| 1148 | spin_unlock(&sbi->s_fc_lock); | | |
| 1149 | nblks = (reason == EXT4_FC_REASON_OK) ? nblks : 0; | | |
| 1150 | trace_ext4_fc_commit_stop(sb, nblks, reason); | | |
| 1151 | commit_time = ktime_to_ns(ktime_sub(ktime_get(), start_time)); | | |
| 1152 | /* | 1167 | /* |
| 1153 | * weight the commit time higher than the average time so we don't | 1168 | * weight the commit time higher than the average time so we |
| 1154 | * react too strongly to vast changes in the commit time | 1169 | * don't react too strongly to vast changes in the commit time |
| 1155 | */ | 1170 | */ |
| 1156 | if (likely(sbi->s_fc_avg_commit_time)) | 1171 | commit_time = ktime_to_ns(ktime_sub(ktime_get(), start_time)); |
| 1157 | sbi->s_fc_avg_commit_time = (commit_time + | 1172 | ext4_fc_update_stats(sb, status, commit_time, nblks); |
| 1158 | sbi->s_fc_avg_commit_time * 3) / 4; | 1173 | return ret; |
| 1159 | else | 1174 | |
| 1160 | sbi->s_fc_avg_commit_time = commit_time; | 1175 | fallback: |
| 1161 | jbd_debug(1, | 1176 | ret = jbd2_fc_end_commit_fallback(journal); |
| 1162 | "Fast commit ended with blks = %d, reason = %d, subtid - %d", | 1177 | ext4_fc_update_stats(sb, status, 0, 0); |
| 1163 | nblks, reason, subtid); | 1178 | return ret; |
| 1164 | if (reason == EXT4_FC_REASON_FC_FAILED) | | |
| 1165 | return jbd2_fc_end_commit_fallback(journal); | | |
| 1166 | if (reason == EXT4_FC_REASON_FC_START_FAILED || | | |
| 1167 | reason == EXT4_FC_REASON_INELIGIBLE) | | |
| 1168 | return jbd2_complete_transaction(journal, commit_tid); | | |
| 1169 | return 0; | | |
| 1170 | } | 1179 | } |
| 1171 | | 1180 | |
| 1172 | /* | 1181 | /* |
| @@ -2124,7 +2133,7 @@ int ext4_fc_info_show(struct seq_file *seq, void *v) · 951 unmodified lines |
| 2124 | "fc stats:\n%ld commits\n%ld ineligible\n%ld numblks\n%lluus avg_commit_time\n", | 2133 | "fc stats:\n%ld commits\n%ld ineligible\n%ld numblks\n%lluus avg_commit_time\n", |
| 2125 | stats->fc_num_commits, stats->fc_ineligible_commits, | 2134 | stats->fc_num_commits, stats->fc_ineligible_commits, |
| 2126 | stats->fc_numblks, | 2135 | stats->fc_numblks, |
| 2127 | div_u64(sbi->s_fc_avg_commit_time, 1000)); | 2136 | div_u64(stats->s_fc_avg_commit_time, 1000)); |
| 2128 | seq_puts(seq, "Ineligible reasons:\n"); | 2137 | seq_puts(seq, "Ineligible reasons:\n"); |
| 2129 | for (i = 0; i < EXT4_FC_REASON_MAX; i++) | 2138 | for (i = 0; i < EXT4_FC_REASON_MAX; i++) |
| 2130 | seq_printf(seq, "\"%s\":\t%d\n", fc_ineligible_reasons[i], | 2139 | seq_printf(seq, "\"%s\":\t%d\n", fc_ineligible_reasons[i], |