Hi Eli,

Thanks for the detailed explanation!

On Tue, Sep 01, 2026 at 10:44:20AM +0200, Eli Billauer wrote:
> On 01/09/2026 9:59, Mike Rapoport wrote:
> > > Would it really make sense to allocate the four buffers separately?
> > > And/or use vmalloc().
> > My understanding is that the buffers don't need to be physically
> > contiguous and vmalloc()ing the entire fifo->mem in one go should work.
> 
> vmalloc() is an interesting point.
> 
> fifo_init(), fifo_write(), fifo_read() and fifo_mem_release() implement a
> FIFO in software that the XillyUSB driver uses internally.
> 
> The memory for this FIFO is allocated in fifo_init() by calling
> __get_free_pages() with requests for up to 64 kiB. With the maximal total
> buffer size of 256 MiB, we have a possibility of 4096 allocations into an
> array of buffers. And if __get_free_pages() fails, the size of each buffer
> is halved in the following attempt, which tries to allocate 8192 buffers,
> each 32 kiB, in this example. And so on.

With vmalloc() you'd get all 256 MiB in one go if there are indeed free 
256 MiB in the system. Unlike get_free_pages()/kmalloc(), vmalloc() does
not try to allocate physically contiguous chunks and it's not affected by
fragmentation.
 
> This mechanism with an array of buffers complicates the implementation of
> the other functions as well.
> 
> So why not replace this with a single call to vmalloc(), possibly asking for
> 256 MiB in one call? That would mean simplifying all four functions.
> 
> When I wrote this driver back in 2020, I avoided vmalloc() because Linus
> wrote "vmalloc() is NOT SOMETHING YOU SHOULD EVER USE!". (See [1]). He also
> noted that vmalloc() is a restricted resource. But that's from 2003, so
> maybe things have changed since?

I believe so, we have kvmalloc() that falls back from kmalloc() to
vmalloc() for larger allocations and we do have about 1k callers of
vmalloc() family.

In 2003 the majority of machines that ran Linux were 32 bit and those had
limited virtual address space. And yes, vmalloc() is slower than kmalloc()
or get_free_pages().
 
> Questions that arise in this context:
> 
> * Does vmalloc() guarantee that non-pageable physical RAM is allocated when
> it returns?

It's not pageable in the sense of demand paging. Some architectures lazily
synchronize vmalloc page tables and this can cause page faults that will
take care of the page table synchronization.

> * Can copy_to/from_user() be used with memory allocated with vmalloc().

Yes.

> * Is vmalloc() guaranteed to successfully allocate memory in the same
> situation that __get_free_pages() could have been used to obtain the same
> amount of memory (in smaller chunks, as with fifo_init() )? Maybe they
> allocate memory from separate memory pools?

The pools are the same in the end, vmalloc() allocates memory using page
allocator, just like __get_free_pages(). The difference is that vmalloc()
does not try to allocate physically contiguous chunks, but rather a
collection of assorted order-0 pages.

This is actually more likely to succeed than multiple large order
allocations.
 
> And most important: In what way, if at all, is memory obtained with
> vmalloc() practically different from memory allocated by __get_free_pages(),
> if it's never used for DMA?

The memory is not physically contiguous and cannot be used for DMA.
Some accesses may generate a fault to synchronize the kernel page tables.
The memory is there, but some processes may have not-yet-synced page
tables.
The allocation itself does more work and it is slower.
 
> Does the API offer clear answers to these questions?
 
Thanks for the detailed explanation

> Thanks in advance,
>    Eli
> 
> [1] https://lwn.net/Articles/57804/

-- 
Sincerely yours,
Mike.

Reply via email to