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
> 


Reply via email to