Use a flexible array member to combine info and instance allocations. Simplifies allocation slightly.
Add __counted_by for extra runtime analysis. Move counting variable assignment to after allocation as kzalloc_flex already does with GCC >= 15. Signed-off-by: Rosen Penev <[email protected]> --- drivers/edac/edac_device.c | 23 ++++++++--------------- drivers/edac/edac_device.h | 4 +--- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/drivers/edac/edac_device.c b/drivers/edac/edac_device.c index cf0d3c2dfc04..9c21997a50e0 100644 --- a/drivers/edac/edac_device.c +++ b/drivers/edac/edac_device.c @@ -58,31 +58,25 @@ edac_device_alloc_ctl_info(unsigned pvt_sz, char *dev_name, unsigned nr_instance char *blk_name, unsigned nr_blocks, unsigned off_val, int device_index) { - struct edac_device_block *dev_blk, *blk_p, *blk; + struct edac_device_block *blk_p, *blk; struct edac_device_instance *dev_inst, *inst; struct edac_device_ctl_info *dev_ctl; unsigned instance, block; + size_t alloc_size; void *pvt; int err; edac_dbg(4, "instances=%d blocks=%d\n", nr_instances, nr_blocks); - dev_ctl = kzalloc_obj(struct edac_device_ctl_info); + alloc_size = struct_size(dev_ctl, instances, nr_instances); + alloc_size += sizeof(*dev_ctl->blocks) * nr_instances * nr_blocks; + dev_ctl = kzalloc(alloc_size, GFP_KERNEL); if (!dev_ctl) return NULL; - dev_inst = kzalloc_objs(struct edac_device_instance, nr_instances); - if (!dev_inst) - goto free; - - dev_ctl->instances = dev_inst; - - dev_blk = kzalloc_objs(struct edac_device_block, - nr_instances * nr_blocks); - if (!dev_blk) - goto free; + dev_ctl->nr_instances = nr_instances; - dev_ctl->blocks = dev_blk; + dev_ctl->blocks = (struct edac_device_block *)(dev_ctl->instances + nr_instances); if (pvt_sz) { pvt = kzalloc(pvt_sz, GFP_KERNEL); @@ -93,7 +87,6 @@ edac_device_alloc_ctl_info(unsigned pvt_sz, char *dev_name, unsigned nr_instance } dev_ctl->dev_idx = device_index; - dev_ctl->nr_instances = nr_instances; /* Default logging of CEs and UEs */ dev_ctl->log_ce = 1; @@ -107,7 +100,7 @@ edac_device_alloc_ctl_info(unsigned pvt_sz, char *dev_name, unsigned nr_instance inst = &dev_inst[instance]; inst->ctl = dev_ctl; inst->nr_blocks = nr_blocks; - blk_p = &dev_blk[instance * nr_blocks]; + blk_p = &dev_ctl->blocks[instance * nr_blocks]; inst->blocks = blk_p; /* name of this instance */ diff --git a/drivers/edac/edac_device.h b/drivers/edac/edac_device.h index 24c1921aa490..4562461a3e8f 100644 --- a/drivers/edac/edac_device.h +++ b/drivers/edac/edac_device.h @@ -203,7 +203,6 @@ struct edac_device_ctl_info { * and the array of those instances */ u32 nr_instances; - struct edac_device_instance *instances; struct edac_device_block *blocks; /* Event counters for the this whole EDAC Device */ @@ -213,6 +212,7 @@ struct edac_device_ctl_info { * device this structure controls */ struct kobject kobj; + struct edac_device_instance instances[] __counted_by(nr_instances); }; /* To get from the instance's wq to the beginning of the ctl structure */ @@ -341,8 +341,6 @@ static inline void __edac_device_free_ctl_info(struct edac_device_ctl_info *ci) { if (ci) { kfree(ci->pvt_info); - kfree(ci->blocks); - kfree(ci->instances); kfree(ci); } } -- 2.54.0

