Re: [PATCH v2] USB: usbfs: replace __get_free_page() with kmalloc()

From: Alan Stern

Date: Mon Nov 09 2026 - 11:17:13 EST


On Sun, Nov 08, 2026 at 10:39:34AM +0200, Mike Rapoport (Microsoft) wrote:
> 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().
>
> Link: https://lore.kernel.org/all/635405e4-9423-4a25-a6e7-e03c8ea0bcbe@xxxxxxxxxx
> Signed-off-by: Mike Rapoport (Microsoft) <rppt@xxxxxxxxxx>
> ---
> 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/8cbe558e-7f53-4ce4-be8e-52fdba9105d4@xxxxxxxxxxxxxxxxxxx
> ---
> v2 changes:
> * drop already merged patches
>
> v1: https://patch.msgid.link/20260830-usb-v1-0-aa349c302246@xxxxxxxxxx
> ---

Acked-by: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx>

> drivers/usb/core/devio.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
> index 101cb94254809..9a7cc7cdf00be 100644
> --- a/drivers/usb/core/devio.c
> +++ b/drivers/usb/core/devio.c
> @@ -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.