From 748fe4399f9194285a91ec8c09141e49a6b470b4 Mon Sep 17 00:00:00 2001 From: "Hailong.Liu" Date: Wed, 22 May 2024 16:03:28 +0800 Subject: HID: Use kvzalloc instead of kzalloc in hid_register_field() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function hid_register_field() might allocate more than 32k, which would use order-4 contiguous memory if the parameter usage exceeds 1024. However, after the system runs for a while, the memory can become heavily fragmented. This increases the likelihood of order-4 page allocation failure. Here’s the relevant log. [71553.093623]kworker/1: 0: page allocation failure: order:4, mode:0x40dc0(GFP_KERNEL|__GFP_COMP|__GFP_ZERO), nodemask=(null),cpuset=/,mems_allowed=0 [71553.093669]Workqueue: events uhid_device_add_worker [71553.093683]Call trace: [71553.093687]: dump_backtrace+0xf4/0x118 [71553.093696]: show_stack+0x18/0x24 [71553.093702]: dump_stack_lvl+0x60/0x7c [71553.093710]: dump_stack+0x18/0x3c [71553.093717]: warn_alloc+0xf4/0x174 [71553.093725]: __alloc_pages_slowpath+0x1ba0/0x1cac [71553.093732]: __alloc_pages+0x460/0x560 [71553.093738]: __kmalloc_large_node+0xbc/0x1f8 [71553.093746]: __kmalloc+0x144/0x254 [71553.093752]: hid_add_field+0x13c/0x308 [71553.093758]: hid_parser_main+0x250/0x298 [71553.093765]: hid_open_report+0x214/0x30c [71553.093771]: mt_probe+0x130/0x258 [71553.093778]: hid_device_probe+0x11c/0x1e4 [71553.093784]: really_probe+0xe4/0x388 [71553.093791]: __driver_probe_device+0xa0/0x12c [71553.093798]: driver_probe_device+0x44/0x214 [71553.093804]: __device_attach_driver+0xdc/0x124 [71553.093812]: bus_for_each_drv+0x88/0xec [71553.093818]: __device_attach+0x84/0x170 [71553.093824]: device_initial_probe+0x14/0x20 [71553.093831]: bus_probe_device+0x48/0xd0 [71553.093836]: device_add+0x248/0x928 [71553.093844]: hid_add_device+0xf8/0x1a4 [71553.093850]: uhid_device_add_worker+0x24/0x144 [71553.093857]: process_one_work+0x158/0x804 [71553.093865]: worker_thread+0x15c/0x494 [71553.093872]: kthread+0xf4/0x1e4 [71553.093880]: ret_from_fork+0x10/0x20 To fix the allocation failure, use kvzalloc() instead of kzalloc(). Signed-off-by: Hailong.Liu Acked-by: Barry Song Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index b1fa0378e8f4..b49d4e2b7512 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -95,9 +95,9 @@ static struct hid_field *hid_register_field(struct hid_report *report, unsigned return NULL; } - field = kzalloc((sizeof(struct hid_field) + - usages * sizeof(struct hid_usage) + - 3 * usages * sizeof(unsigned int)), GFP_KERNEL); + field = kvzalloc((sizeof(struct hid_field) + + usages * sizeof(struct hid_usage) + + 3 * usages * sizeof(unsigned int)), GFP_KERNEL); if (!field) return NULL; @@ -661,7 +661,7 @@ static void hid_free_report(struct hid_report *report) kfree(report->field_entries); for (n = 0; n < report->maxfield; n++) - kfree(report->field[n]); + kvfree(report->field[n]); kfree(report); } -- cgit From b81881b9c10e1f5eafc02df026663b824610d537 Mon Sep 17 00:00:00 2001 From: Danny Kaehn Date: Wed, 5 Jun 2024 18:12:45 -0500 Subject: HID: usbhid: Share USB device firmware node with child HID device USB HID core now shares its fwnode with its child HID device. Since there can only be one HID device on a USB interface, it is redundant to specify a hid node under the USB device. This allows usb HID device drivers to be described in firmware and make use of device properties. Signed-off-by: Danny Kaehn Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20240605-cp2112-dt-v11-2-d55f0f945a62@plexus.com Signed-off-by: Benjamin Tissoires --- drivers/hid/usbhid/hid-core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index a90ed2ceae84..cb687ea7325c 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -1374,6 +1375,7 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id * hid->hiddev_report_event = hiddev_report_event; #endif hid->dev.parent = &intf->dev; + device_set_node(&hid->dev, dev_fwnode(&intf->dev)); hid->bus = BUS_USB; hid->vendor = le16_to_cpu(dev->descriptor.idVendor); hid->product = le16_to_cpu(dev->descriptor.idProduct); -- cgit