Message ID | 20180215034050.GA5775@bombadil.infradead.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Wed, Feb 14, 2018 at 07:40:50PM -0800, Matthew Wilcox wrote: > > a_foo = kvzalloc_struct_buf(struct foo, struct bar, nr_bars); > > > > or, of course. > > > > a_foo = kvzalloc_struct_buf(typeof(*a_foo), typeof(a_foo->bar[0]), > > nr_bars); > > > > or whatever. This version works, although it's more typing in the callers: - attr_group = kvzalloc_struct(attr_group, attrs, i + 1, + attr_group = kvzalloc_struct(typeof(*attr_group), attrs, i + 1, GFP_KERNEL); ... - dev_dax = kvzalloc_struct(dev_dax, res, count, GFP_KERNEL); + dev_dax = kvzalloc_struct(struct dev_dax, res, count, GFP_KERNEL); ... -#define kvzalloc_struct(p, member, n, gfp) \ - (typeof(p))kvzalloc_ab_c(n, \ - sizeof(*(p)->member) + __must_be_array((p)->member), \ - offsetof(typeof(*(p)), member), gfp) +#define kvzalloc_struct(s, member, n, gfp) ({ \ + s *__p; \ + (s *)kvzalloc_ab_c(n, \ + sizeof(*(__p)->member) + __must_be_array((__p)->member),\ + offsetof(s, member), gfp); \ +}) Gives all the same checking as the current version, and doesn't involve passing an uninitialised pointer to the macro. It also looks pretty similar: p = kvzalloc(sizeof(*p), GFP_KERNEL); p = kvzalloc_struct(typeof(*p), array, count, GFP_KERNEL); p = kvzalloc_array(sizeof(*p), count);
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c index 7874c980d569..5cd3e127bea8 100644 --- a/arch/x86/events/intel/uncore.c +++ b/arch/x86/events/intel/uncore.c @@ -792,7 +792,7 @@ static void uncore_type_exit(struct intel_uncore_type *type) kfree(type->pmus); type->pmus = NULL; } - kfree(type->events_group); + kvfree(type->events_group); type->events_group = NULL; } @@ -805,8 +805,6 @@ static void uncore_types_exit(struct intel_uncore_type **types) static int __init uncore_type_init(struct intel_uncore_type *type, bool setid) { struct intel_uncore_pmu *pmus; - struct attribute_group *attr_group; - struct attribute **attrs; size_t size; int i, j; @@ -831,21 +829,24 @@ static int __init uncore_type_init(struct intel_uncore_type *type, bool setid) 0, type->num_counters, 0, 0); if (type->event_descs) { + struct { + struct attribute_group group; + struct attribute *attrs[]; + } *attr_group; for (i = 0; type->event_descs[i].attr.attr.name; i++); - attr_group = kzalloc(sizeof(struct attribute *) * (i + 1) + - sizeof(*attr_group), GFP_KERNEL); + attr_group = kvzalloc_struct(attr_group, attrs, i + 1, + GFP_KERNEL); if (!attr_group) goto err; - attrs = (struct attribute **)(attr_group + 1); - attr_group->name = "events"; - attr_group->attrs = attrs; + attr_group->group.name = "events"; + attr_group->group.attrs = attr_group->attrs; for (j = 0; j < i; j++) - attrs[j] = &type->event_descs[j].attr.attr; + attr_group->attrs[j] = &type->event_descs[j].attr.attr; - type->events_group = attr_group; + type->events_group = &attr_group->group; } type->pmu_group = &uncore_pmu_attr_group;