Message ID | 20211019002656.17745-1-wangyugui@e16-tech.com (mailing list archive) |
---|---|
State | Accepted |
Delegated to: | Jason Gunthorpe |
Headers | show |
Series | infiniband: change some kmalloc to kvmalloc to support CONFIG_PROVE_LOCKING=y | expand |
On Tue, Oct 19, 2021 at 08:26:56AM +0800, wangyugui wrote: > When CONFIG_PROVE_LOCKING=y, one kmalloc of infiniband hit the max alloc size limitation. > > WARNING: CPU: 36 PID: 8 at mm/page_alloc.c:5350 __alloc_pages+0x27e/0x3e0 > Call Trace: > kmalloc_order+0x2a/0xb0 > kmalloc_order_trace+0x19/0xf0 > __kmalloc+0x231/0x270 > ib_setup_port_attrs+0xd8/0x870 [ib_core] > ib_register_device+0x419/0x4e0 [ib_core] > bnxt_re_task+0x208/0x2d0 [bnxt_re] > > change this kmalloc to kvmalloc to support CONFIG_PROVE_LOCKING=y > > Signed-off-by: wangyugui <wangyugui@e16-tech.com> > --- > drivers/infiniband/core/sysfs.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) Huh? what causes ib_port to get larger than MAX_ORDER? The only array is attrs_list and I don't see something that scales with Jason
Hi, > On Tue, Oct 19, 2021 at 08:26:56AM +0800, wangyugui wrote: > > When CONFIG_PROVE_LOCKING=y, one kmalloc of infiniband hit the max alloc size limitation. > > > > WARNING: CPU: 36 PID: 8 at mm/page_alloc.c:5350 __alloc_pages+0x27e/0x3e0 > > Call Trace: > > kmalloc_order+0x2a/0xb0 > > kmalloc_order_trace+0x19/0xf0 > > __kmalloc+0x231/0x270 > > ib_setup_port_attrs+0xd8/0x870 [ib_core] > > ib_register_device+0x419/0x4e0 [ib_core] > > bnxt_re_task+0x208/0x2d0 [bnxt_re] > > > > change this kmalloc to kvmalloc to support CONFIG_PROVE_LOCKING=y > > > > Signed-off-by: wangyugui <wangyugui@e16-tech.com> > > --- > > drivers/infiniband/core/sysfs.c | 4 ++-- > > 1 file changed, 2 insertions(+), 2 deletions(-) > > Huh? what causes ib_port to get larger than MAX_ORDER? > > The only array is attrs_list and I don't see something that scales > with The array size is not fixed. so it maybe a little big in some case. struct ib_port { struct kobject kobj; struct ib_device *ibdev; struct gid_attr_group *gid_attr_group; struct hw_stats_port_data *hw_stats_data; struct attribute_group groups[3]; const struct attribute_group *groups_list[5]; u32 port_num; struct port_table_attribute attrs_list[]; }; => struct port_table_attribute { struct ib_port_attribute attr; => struct ib_port_attribute { struct attribute attr; => struct attribute { const char *name; umode_t mode; #ifdef CONFIG_DEBUG_LOCK_ALLOC bool ignore_lockdep:1; struct lock_class_key *key; struct lock_class_key skey; #endif }; When CONFIG_PROVE_LOCKING=y, we need CONFIG_DEBUG_LOCK_ALLOC=y too. This problem happen when CONFIG_PROVE_LOCKING=y(CONFIG_DEBUG_LOCK_ALLOC=y), but not happen when CONFIG_PROVE_LOCKING=n(CONFIG_DEBUG_LOCK_ALLOC=n). Best Regards Wang Yugui (wangyugui@e16-tech.com) 2021/10/19
On Tue, Oct 19, 2021 at 08:26:56AM +0800, wangyugui wrote: > When CONFIG_PROVE_LOCKING=y, one kmalloc of infiniband hit the max alloc size limitation. > > WARNING: CPU: 36 PID: 8 at mm/page_alloc.c:5350 __alloc_pages+0x27e/0x3e0 > Call Trace: > kmalloc_order+0x2a/0xb0 > kmalloc_order_trace+0x19/0xf0 > __kmalloc+0x231/0x270 > ib_setup_port_attrs+0xd8/0x870 [ib_core] > ib_register_device+0x419/0x4e0 [ib_core] > bnxt_re_task+0x208/0x2d0 [bnxt_re] > > change this kmalloc to kvmalloc to support CONFIG_PROVE_LOCKING=y > > Signed-off-by: wangyugui <wangyugui@e16-tech.com> > --- > drivers/infiniband/core/sysfs.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) Applied to for-next, thanks Jason
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c index 6146c3c1cbe5..8d709986b88c 100644 --- a/drivers/infiniband/core/sysfs.c +++ b/drivers/infiniband/core/sysfs.c @@ -757,7 +757,7 @@ static void ib_port_release(struct kobject *kobj) if (port->hw_stats_data) kfree(port->hw_stats_data->stats); kfree(port->hw_stats_data); - kfree(port); + kvfree(port); } static void ib_port_gid_attr_release(struct kobject *kobj) @@ -1189,7 +1189,7 @@ static struct ib_port *setup_port(struct ib_core_device *coredev, int port_num, struct ib_port *p; int ret; - p = kzalloc(struct_size(p, attrs_list, + p = kvzalloc(struct_size(p, attrs_list, attr->gid_tbl_len + attr->pkey_tbl_len), GFP_KERNEL); if (!p)
When CONFIG_PROVE_LOCKING=y, one kmalloc of infiniband hit the max alloc size limitation. WARNING: CPU: 36 PID: 8 at mm/page_alloc.c:5350 __alloc_pages+0x27e/0x3e0 Call Trace: kmalloc_order+0x2a/0xb0 kmalloc_order_trace+0x19/0xf0 __kmalloc+0x231/0x270 ib_setup_port_attrs+0xd8/0x870 [ib_core] ib_register_device+0x419/0x4e0 [ib_core] bnxt_re_task+0x208/0x2d0 [bnxt_re] change this kmalloc to kvmalloc to support CONFIG_PROVE_LOCKING=y Signed-off-by: wangyugui <wangyugui@e16-tech.com> --- drivers/infiniband/core/sysfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)