Skip to contentSkip to conversation

USB: usbfs: replace __get_free_page() with kmalloc()

PATCH In review Mike Rapoport (Microsoft) 2 participants 2 messages Nov 8 – Nov 9

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH v2 1/1 USB: usbfs: replace __get_free_page() with kmalloc()

do_proc_control() allocates a temporary buffer for the data stage of a control transfer issued from userspace.

This buffer can be allocated with kmalloc() as there's nothing special about it to go directly to the page allocator.

kmalloc() provides a better API that does not require ugly casts and kfree() does not need to know the size of the freed object.

Performance difference between kmalloc() and __get_free_pages() is not measurable as both allocators take an object/page from a per-CPU list for fast path allocations.

For the slow path the performance is anyway determined by the amount of reclaim involved rather than by what allocator is used.

Replace use of __get_free_page() with kmalloc() and free_page() with kfree().

---
This is essentially a resend of the "USB: usbfs: replace __get_free_page() with kmalloc()" patch that fell between the cracks.

Alan and Vlastimil agreed on v1 that the kmalloc() overhead does not matter for usbfs memory accounting:

https://lore.kernel.org/all/[email protected]
---
v2 changes:
* drop already merged patches

v1: https://patch.msgid.link/[email protected]

---
 drivers/usb/core/devio.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/usb/core/devio.c +2 -2
index 101cb94254809..9a7cc7cdf00be 100644
@@ -1190,7 +1190,7 @@ static int do_proc_control(struct usb_dev_state *ps,
 		return ret;
 
 	ret = -ENOMEM;
-	tbuf = (unsigned char *)__get_free_page(GFP_KERNEL);
+	tbuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
 	if (!tbuf)
 		goto done;
 	urb = usb_alloc_urb(0, GFP_NOIO);
@@ -1265,7 +1265,7 @@ static int do_proc_control(struct usb_dev_state *ps,
  done:
 	kfree(dr);
 	usb_free_urb(urb);
-	free_page((unsigned long) tbuf);
+	kfree(tbuf);
 	usbfs_decrease_memory_usage(PAGE_SIZE + sizeof(struct urb) +
 			sizeof(struct usb_ctrlrequest));
 	return ret;

---
base-commit: 6628e7d4c6b25c8d18f1345e3a20d21829aae7e4
change-id: 20260829-usb-ad052ea1ffad

--
Sincerely yours,
Mike.

Acked-by on v2 1/1
#1 lore raw
Quoted 28 lines · Mike Rapoport (Microsoft)

do_proc_control() allocates a temporary buffer for the data stage of a control transfer issued from userspace.

This buffer can be allocated with kmalloc() as there's nothing special about it to go directly to the page allocator.

kmalloc() provides a better API that does not require ugly casts and kfree() does not need to know the size of the freed object.

Performance difference between kmalloc() and __get_free_pages() is not measurable as both allocators take an object/page from a per-CPU list for fast path allocations.

For the slow path the performance is anyway determined by the amount of reclaim involved rather than by what allocator is used.

Replace use of __get_free_page() with kmalloc() and free_page() with kfree().

---
This is essentially a resend of the "USB: usbfs: replace __get_free_page() with kmalloc()" patch that fell between the cracks.

Alan and Vlastimil agreed on v1 that the kmalloc() overhead does not matter for usbfs memory accounting:

Quoted 7 lines

https://lore.kernel.org/all/[email protected]
---
v2 changes:
* drop already merged patches

v1: https://patch.msgid.link/[email protected]
---

Quoted 33 lines
 drivers/usb/core/devio.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/usb/core/devio.c +2 -3
index 101cb94254809..9a7cc7cdf00be 100644
@@ -1190,7 +1190,7 @@ static int do_proc_control(struct usb_dev_state *ps,
 		return ret;
 
 	ret = -ENOMEM;
-	tbuf = (unsigned char *)__get_free_page(GFP_KERNEL);
+	tbuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
 	if (!tbuf)
 		goto done;
 	urb = usb_alloc_urb(0, GFP_NOIO);
@@ -1265,7 +1265,7 @@ static int do_proc_control(struct usb_dev_state *ps,
  done:
 	kfree(dr);
 	usb_free_urb(urb);
-	free_page((unsigned long) tbuf);
+	kfree(tbuf);
 	usbfs_decrease_memory_usage(PAGE_SIZE + sizeof(struct urb) +
 			sizeof(struct usb_ctrlrequest));
 	return ret;
 
---

base-commit: 6628e7d4c6b25c8d18f1345e3a20d21829aae7e4
change-id: 20260829-usb-ad052ea1ffad

--
Sincerely yours,
Mike.