@@ -28,6 +28,63 @@ enum {
2828
2929/// Caching block device operations ///
3030
31+ enum {
32+ LFS_CACHE_TRACE_EVICT ,
33+ LFS_CACHE_TRACE_BYPASS ,
34+ LFS_CACHE_TRACE_DROP ,
35+ };
36+
37+ #ifdef LFS_CACHE_TRACE
38+ #define LFS_TRACE2 printf
39+ static lfs_size_t read_cache_start_used = 0 , read_cache_end_used = 0 ;
40+ static lfs_size_t read_cache_traffic = 0 ;
41+ static int read_cache_alloc_line = 0 , read_cache_recache = 0 ;
42+ static inline void lfs_cache_trace_log (lfs_t * lfs , int op , lfs_cache_t * rcache , lfs_block_t block , lfs_off_t off , lfs_size_t size , int line )
43+ {
44+ switch (op ) {
45+ case LFS_CACHE_TRACE_EVICT :
46+ case LFS_CACHE_TRACE_DROP :
47+ if (rcache -> block != LFS_BLOCK_NULL ) {
48+ LFS_TRACE2 ("cache %d:%d size %d access=[%d-%d] byte_read=%d line=%d\n" ,
49+ rcache -> block , rcache -> off , rcache -> size ,
50+ read_cache_start_used - rcache -> off ,
51+ read_cache_end_used - rcache -> off ,
52+ read_cache_traffic , read_cache_alloc_line );
53+ if (rcache -> block == block )
54+ read_cache_recache ++ ;
55+ else if (read_cache_recache ) {
56+ LFS_TRACE2 ("cache recache for block %d number %d line=%d\n" ,
57+ rcache -> block , read_cache_recache , read_cache_alloc_line );
58+ read_cache_recache = 0 ;
59+ }
60+ }
61+ read_cache_start_used = off + lfs -> cfg -> cache_size ;
62+ read_cache_end_used = 0 ;
63+ read_cache_traffic = 0 ;
64+ read_cache_alloc_line = line ;
65+
66+ break ;
67+ case LFS_CACHE_TRACE_BYPASS :
68+ LFS_TRACE2 ("cache no %d:%d size %d line=%d\n" , block , off , size , line );
69+ break ;
70+ }
71+ }
72+
73+ static inline void lfs_cache_trace_access (lfs_cache_t * rcache , lfs_off_t off , lfs_size_t size )
74+ {
75+ (void )rcache ;
76+ if (read_cache_end_used < off + size )
77+ read_cache_end_used = off + size ;
78+ if (read_cache_start_used > off )
79+ read_cache_start_used = off ;
80+
81+ read_cache_traffic += size ;
82+ }
83+ #else
84+ #define lfs_cache_trace_log (...)
85+ #define lfs_cache_trace_access (...)
86+ #endif
87+
3188static inline void lfs_cache_drop (lfs_t * lfs , lfs_cache_t * rcache ) {
3289 // do not zero, cheaper if cache is readonly or only going to be
3390 // written with identical data (during relocates)
@@ -41,11 +98,13 @@ static inline void lfs_cache_zero(lfs_t *lfs, lfs_cache_t *pcache) {
4198 pcache -> block = LFS_BLOCK_NULL ;
4299}
43100
44- static int lfs_bd_read (lfs_t * lfs ,
101+ #define lfs_bd_read (...) lfs_bd_read_raw(__VA_ARGS__, __LINE__)
102+ static int lfs_bd_read_raw (lfs_t * lfs ,
45103 const lfs_cache_t * pcache , lfs_cache_t * rcache , lfs_size_t hint ,
46104 lfs_block_t block , lfs_off_t off ,
47- void * buffer , lfs_size_t size ) {
105+ void * buffer , lfs_size_t size , int line ) {
48106 uint8_t * data = buffer ;
107+ (void )line ;
49108 if (off + size > lfs -> cfg -> block_size
50109 || (lfs -> block_count && block >= lfs -> block_count )) {
51110 return LFS_ERR_CORRUPT ;
@@ -77,6 +136,7 @@ static int lfs_bd_read(lfs_t *lfs,
77136 // is already in rcache?
78137 diff = lfs_min (diff , rcache -> size - (off - rcache -> off ));
79138 memcpy (data , & rcache -> buffer [off - rcache -> off ], diff );
139+ lfs_cache_trace_access (rcache , off , diff );
80140
81141 data += diff ;
82142 off += diff ;
@@ -97,12 +157,15 @@ static int lfs_bd_read(lfs_t *lfs,
97157 return err ;
98158 }
99159
160+ lfs_cache_trace_log (lfs , LFS_CACHE_TRACE_BYPASS , rcache , block , off , diff , line );
100161 data += diff ;
101162 off += diff ;
102163 size -= diff ;
164+
103165 continue ;
104166 }
105167
168+ lfs_cache_trace_log (lfs , LFS_CACHE_TRACE_EVICT , rcache , block , off , diff , line );
106169 // load to cache, first condition can no longer fail
107170 LFS_ASSERT (!lfs -> block_count || block < lfs -> block_count );
108171 rcache -> block = block ;
0 commit comments