Hi I accepted this patch. Thanks.
Mikulas On Mon, 7 Sep 2026, Henry Wong wrote: > wc_entry.index removed: This can be computed by pointer arithmetic without > storage. > wc_entry.age reduced to 32 bits: It only needs to be big enough to hold > max_age, which is limited to well below 32-bit range. > > Reduces wc_entry size from 56 bytes to 48 bytes (from 72 to 64 bytes if > DM_WRITECACHE_HANDLE_HARDWARE_ERRORS enabled). > > Signed-off-by: Henry Wong <[email protected]> > --- > drivers/md/dm-writecache.c | 39 ++++++++++++++++++-------------------- > 1 file changed, 18 insertions(+), 21 deletions(-) > > diff --git a/drivers/md/dm-writecache.c b/drivers/md/dm-writecache.c > index 978646f71f99..68e3fb300fc1 100644 > --- a/drivers/md/dm-writecache.c > +++ b/drivers/md/dm-writecache.c > @@ -81,15 +81,9 @@ struct wc_memory_superblock { > struct wc_entry { > struct rb_node rb_node; > struct list_head lru; > + u32 age; // jiffies > unsigned short wc_list_contiguous; > -#if BITS_PER_LONG == 64 > - bool write_in_progress : 1; > - unsigned long index : 47; > -#else > bool write_in_progress; > - unsigned long index; > -#endif > - unsigned long age; > #ifdef DM_WRITECACHE_HANDLE_HARDWARE_ERRORS > uint64_t original_sector; > uint64_t seq_count; > @@ -389,20 +383,28 @@ static struct wc_memory_superblock *sb(struct > dm_writecache *wc) > return wc->memory_map; > } > > +static inline unsigned long wc_entry_index(const struct wc_entry *base, > const struct wc_entry *entry) > +{ > + return entry - base; > +} > + > static struct wc_memory_entry *memory_entry(struct dm_writecache *wc, struct > wc_entry *e) > { > - return &sb(wc)->entries[e->index]; > + const unsigned long index = wc_entry_index(wc->entries, e); > + return &sb(wc)->entries[index]; > } > > static void *memory_data(struct dm_writecache *wc, struct wc_entry *e) > { > - return (char *)wc->block_start + (e->index << wc->block_size_bits); > + const unsigned long index = wc_entry_index(wc->entries, e); > + return (char *)wc->block_start + (index << wc->block_size_bits); > } > > static sector_t cache_sector(struct dm_writecache *wc, struct wc_entry *e) > { > + const unsigned long index = wc_entry_index(wc->entries, e); > return wc->start_sector + wc->metadata_sectors + > - ((sector_t)e->index << (wc->block_size_bits - SECTOR_SHIFT)); > + ((sector_t)index << (wc->block_size_bits - SECTOR_SHIFT)); > } > > static uint64_t read_original_sector(struct dm_writecache *wc, struct > wc_entry *e) > @@ -668,7 +670,7 @@ static void writecache_insert_entry(struct dm_writecache > *wc, struct wc_entry *i > rb_link_node(&ins->rb_node, parent, node); > rb_insert_color(&ins->rb_node, &wc->tree); > list_add(&ins->lru, &wc->lru); > - ins->age = jiffies; > + ins->age = (u32)jiffies; > } > > static void writecache_unlink(struct dm_writecache *wc, struct wc_entry *e) > @@ -969,7 +971,6 @@ static int writecache_alloc_entries(struct dm_writecache > *wc) > for (b = 0; b < wc->n_blocks; b++) { > struct wc_entry *e = &wc->entries[b]; > > - e->index = b; > e->write_in_progress = false; > cond_resched(); > } > @@ -1986,7 +1987,7 @@ static void writecache_writeback(struct work_struct > *work) > while (!list_empty(&wc->lru) && > (wc->writeback_all || > wc->freelist_size + wc->writeback_size <= > wc->freelist_low_watermark || > - (jiffies - container_of(wc->lru.prev, struct wc_entry, > lru)->age >= > + ((u32)(jiffies - container_of(wc->lru.prev, struct wc_entry, > lru)->age) >= > wc->max_age - wc->max_age / MAX_AGE_DIV))) { > > n_walked++; > @@ -2107,7 +2108,6 @@ static int calculate_memory_size(uint64_t device_size, > unsigned int block_size, > size_t *n_blocks_p, size_t > *n_metadata_blocks_p) > { > uint64_t n_blocks, offset; > - struct wc_entry e; > > n_blocks = device_size; > do_div(n_blocks, block_size + sizeof(struct wc_memory_entry)); > @@ -2126,11 +2126,6 @@ static int calculate_memory_size(uint64_t device_size, > unsigned int block_size, > n_blocks--; > } > > - /* check if the bit field overflows */ > - e.index = n_blocks; > - if (e.index != n_blocks) > - return -EFBIG; > - > if (n_blocks_p) > *n_blocks_p = n_blocks; > if (n_metadata_blocks_p) > @@ -2444,13 +2439,15 @@ static int writecache_ctr(struct dm_target *ti, > unsigned int argc, char **argv) > wc->autocommit_time_set = true; > } else if (!strcasecmp(string, "max_age") && opt_params >= 1) { > unsigned int max_age_msecs; > + unsigned long max_age_jiffies; > > string = dm_shift_arg(&as), opt_params--; > if (sscanf(string, "%u%c", &max_age_msecs, &dummy) != 1) > goto invalid_optional; > - if (max_age_msecs > 86400000) > + max_age_jiffies = msecs_to_jiffies(max_age_msecs); > + if (max_age_jiffies >= min(MAX_JIFFY_OFFSET, (7 << > 28))) // 7/8ths of 1 << 31 > goto invalid_optional; > - wc->max_age = msecs_to_jiffies(max_age_msecs); > + wc->max_age = max_age_jiffies; > wc->max_age_set = true; > wc->max_age_value = max_age_msecs; > } else if (!strcasecmp(string, "cleaner")) { > -- > 2.52.0 >
