Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

f2fs: add page-order information for large folio reads in iostat

Track read folio counts by order in F2FS iostat sysfs and tracepoints.

Signed-off-by: Daniel Lee <chullee@google.com>
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>

authored by

Daniel Lee and committed by
Jaegeuk Kim
cb8ff3ea 1583a7de

+65 -5
+4
fs/f2fs/data.c
··· 2508 2508 if (!folio) 2509 2509 goto out; 2510 2510 2511 + f2fs_update_read_folio_count(F2FS_I_SB(inode), folio); 2512 + 2511 2513 folio_in_bio = false; 2512 2514 index = folio->index; 2513 2515 offset = 0; ··· 2683 2681 folio = readahead_folio(rac); 2684 2682 prefetchw(&folio->flags); 2685 2683 } 2684 + 2685 + f2fs_update_read_folio_count(F2FS_I_SB(inode), folio); 2686 2686 2687 2687 #ifdef CONFIG_F2FS_FS_COMPRESSION 2688 2688 index = folio->index;
+3
fs/f2fs/f2fs.h
··· 10 10 11 11 #include <linux/uio.h> 12 12 #include <linux/types.h> 13 + #include <linux/mmzone.h> 13 14 #include <linux/page-flags.h> 14 15 #include <linux/slab.h> 15 16 #include <linux/crc32.h> ··· 2035 2034 unsigned long long iostat_count[NR_IO_TYPE]; 2036 2035 unsigned long long iostat_bytes[NR_IO_TYPE]; 2037 2036 unsigned long long prev_iostat_bytes[NR_IO_TYPE]; 2037 + unsigned long long iostat_read_folio_count[NR_PAGE_ORDERS]; 2038 + unsigned long long prev_iostat_read_folio_count[NR_PAGE_ORDERS]; 2038 2039 bool iostat_enable; 2039 2040 unsigned long iostat_next_period; 2040 2041 unsigned int iostat_period_ms;
+37 -1
fs/f2fs/iostat.c
··· 34 34 { 35 35 struct super_block *sb = seq->private; 36 36 struct f2fs_sb_info *sbi = F2FS_SB(sb); 37 + int i; 37 38 38 39 if (!sbi->iostat_enable) 39 40 return 0; ··· 77 76 IOSTAT_INFO_SHOW("fs node", FS_NODE_READ_IO); 78 77 IOSTAT_INFO_SHOW("fs meta", FS_META_READ_IO); 79 78 79 + /* print read folio order stats */ 80 + seq_printf(seq, "%-23s", "fs read folio order:"); 81 + for (i = 0; i < NR_PAGE_ORDERS; i++) 82 + seq_printf(seq, " %llu", sbi->iostat_read_folio_count[i]); 83 + seq_putc(seq, '\n'); 84 + 80 85 /* print other IOs */ 81 86 seq_puts(seq, "[OTHER]\n"); 82 87 IOSTAT_INFO_SHOW("fs discard", FS_DISCARD_IO); ··· 120 113 static inline void f2fs_record_iostat(struct f2fs_sb_info *sbi) 121 114 { 122 115 unsigned long long iostat_diff[NR_IO_TYPE]; 116 + unsigned long long read_folio_count_diff[NR_PAGE_ORDERS]; 123 117 int i; 124 118 unsigned long flags; 125 119 ··· 141 133 sbi->prev_iostat_bytes[i]; 142 134 sbi->prev_iostat_bytes[i] = sbi->iostat_bytes[i]; 143 135 } 136 + 137 + for (i = 0; i < NR_PAGE_ORDERS; i++) { 138 + read_folio_count_diff[i] = sbi->iostat_read_folio_count[i] - 139 + sbi->prev_iostat_read_folio_count[i]; 140 + sbi->prev_iostat_read_folio_count[i] = sbi->iostat_read_folio_count[i]; 141 + } 144 142 spin_unlock_irqrestore(&sbi->iostat_lock, flags); 145 143 146 - trace_f2fs_iostat(sbi, iostat_diff); 144 + trace_f2fs_iostat(sbi, iostat_diff, read_folio_count_diff); 147 145 148 146 __record_iostat_latency(sbi); 149 147 } ··· 165 151 sbi->iostat_bytes[i] = 0; 166 152 sbi->prev_iostat_bytes[i] = 0; 167 153 } 154 + for (i = 0; i < NR_PAGE_ORDERS; i++) { 155 + sbi->iostat_read_folio_count[i] = 0; 156 + sbi->prev_iostat_read_folio_count[i] = 0; 157 + } 168 158 spin_unlock_irq(&sbi->iostat_lock); 169 159 170 160 spin_lock_irq(&sbi->iostat_lat_lock); ··· 181 163 { 182 164 sbi->iostat_bytes[type] += io_bytes; 183 165 sbi->iostat_count[type]++; 166 + } 167 + 168 + void f2fs_update_read_folio_count(struct f2fs_sb_info *sbi, struct folio *folio) 169 + { 170 + unsigned int order = folio_order(folio); 171 + unsigned long flags; 172 + 173 + if (!sbi->iostat_enable) 174 + return; 175 + 176 + if (order >= NR_PAGE_ORDERS) 177 + order = NR_PAGE_ORDERS - 1; 178 + 179 + spin_lock_irqsave(&sbi->iostat_lock, flags); 180 + sbi->iostat_read_folio_count[order]++; 181 + spin_unlock_irqrestore(&sbi->iostat_lock, flags); 182 + 183 + f2fs_record_iostat(sbi); 184 184 } 185 185 186 186 void f2fs_update_iostat(struct f2fs_sb_info *sbi, struct inode *inode,
+4
fs/f2fs/iostat.h
··· 34 34 extern void f2fs_reset_iostat(struct f2fs_sb_info *sbi); 35 35 extern void f2fs_update_iostat(struct f2fs_sb_info *sbi, struct inode *inode, 36 36 enum iostat_type type, unsigned long long io_bytes); 37 + extern void f2fs_update_read_folio_count(struct f2fs_sb_info *sbi, 38 + struct folio *folio); 37 39 38 40 struct bio_iostat_ctx { 39 41 struct f2fs_sb_info *sbi; ··· 70 68 #else 71 69 static inline void f2fs_update_iostat(struct f2fs_sb_info *sbi, struct inode *inode, 72 70 enum iostat_type type, unsigned long long io_bytes) {} 71 + static inline void f2fs_update_read_folio_count(struct f2fs_sb_info *sbi, 72 + struct folio *folio) {} 73 73 static inline void iostat_update_and_unbind_ctx(struct bio *bio) {} 74 74 static inline void iostat_alloc_and_bind_ctx(struct f2fs_sb_info *sbi, 75 75 struct bio *bio, struct bio_post_read_ctx *ctx) {}
+17 -4
include/trace/events/f2fs.h
··· 2116 2116 #ifdef CONFIG_F2FS_IOSTAT 2117 2117 TRACE_EVENT(f2fs_iostat, 2118 2118 2119 - TP_PROTO(struct f2fs_sb_info *sbi, unsigned long long *iostat), 2119 + TP_PROTO(struct f2fs_sb_info *sbi, unsigned long long *iostat, 2120 + unsigned long long *read_folio_count), 2120 2121 2121 - TP_ARGS(sbi, iostat), 2122 + TP_ARGS(sbi, iostat, read_folio_count), 2122 2123 2123 2124 TP_STRUCT__entry( 2124 2125 __field(dev_t, dev) ··· 2151 2150 __field(unsigned long long, fs_mrio) 2152 2151 __field(unsigned long long, fs_discard) 2153 2152 __field(unsigned long long, fs_reset_zone) 2153 + __array(unsigned long long, read_folio_count, 11) 2154 2154 ), 2155 2155 2156 2156 TP_fast_assign( ··· 2184 2182 __entry->fs_mrio = iostat[FS_META_READ_IO]; 2185 2183 __entry->fs_discard = iostat[FS_DISCARD_IO]; 2186 2184 __entry->fs_reset_zone = iostat[FS_ZONE_RESET_IO]; 2185 + memset(__entry->read_folio_count, 0, sizeof(__entry->read_folio_count)); 2186 + memcpy(__entry->read_folio_count, read_folio_count, 2187 + sizeof(unsigned long long) * min_t(int, NR_PAGE_ORDERS, 11)); 2187 2188 ), 2188 2189 2189 2190 TP_printk("dev = (%d,%d), " ··· 2199 2194 "app [read=%llu (direct=%llu, buffered=%llu), mapped=%llu], " 2200 2195 "compr(buffered=%llu, mapped=%llu)], " 2201 2196 "fs [data=%llu, (gc_data=%llu, cdata=%llu), " 2202 - "node=%llu, meta=%llu]", 2197 + "node=%llu, meta=%llu], " 2198 + "read_folio_count [0=%llu, 1=%llu, 2=%llu, 3=%llu, 4=%llu, " 2199 + "5=%llu, 6=%llu, 7=%llu, 8=%llu, 9=%llu, 10=%llu]", 2203 2200 show_dev(__entry->dev), __entry->app_wio, __entry->app_dio, 2204 2201 __entry->app_bio, __entry->app_mio, __entry->app_bcdio, 2205 2202 __entry->app_mcdio, __entry->fs_dio, __entry->fs_cdio, ··· 2212 2205 __entry->app_rio, __entry->app_drio, __entry->app_brio, 2213 2206 __entry->app_mrio, __entry->app_bcrio, __entry->app_mcrio, 2214 2207 __entry->fs_drio, __entry->fs_gdrio, 2215 - __entry->fs_cdrio, __entry->fs_nrio, __entry->fs_mrio) 2208 + __entry->fs_cdrio, __entry->fs_nrio, __entry->fs_mrio, 2209 + __entry->read_folio_count[0], __entry->read_folio_count[1], 2210 + __entry->read_folio_count[2], __entry->read_folio_count[3], 2211 + __entry->read_folio_count[4], __entry->read_folio_count[5], 2212 + __entry->read_folio_count[6], __entry->read_folio_count[7], 2213 + __entry->read_folio_count[8], __entry->read_folio_count[9], 2214 + __entry->read_folio_count[10]) 2216 2215 ); 2217 2216 2218 2217 #ifndef __F2FS_IOSTAT_LATENCY_TYPE