Hi Michael,

On Wed, 19 Mar 2025 at 21:29, Michael Kelley <mhkli...@outlook.com> wrote:
> From: Helge Deller <del...@gmx.de> Sent: Tuesday, March 18, 2025 1:16 AM
> > On 3/18/25 03:05, Michael Kelley wrote:
> > > I've been trying to get mmap() working with the hyperv_fb.c fbdev driver, 
> > > which
> > > is for Linux guests running on Microsoft's Hyper-V hypervisor. The 
> > > hyperv_fb driver
> > > uses fbdev deferred I/O for performance reasons. But it looks to me like 
> > > fbdev
> > > deferred I/O is fundamentally broken when the underlying framebuffer 
> > > memory
> > > is allocated from kernel memory (alloc_pages or dma_alloc_coherent).
> > >
> > > The hyperv_fb.c driver may allocate the framebuffer memory in several 
> > > ways,
> > > depending on the size of the framebuffer specified by the Hyper-V host 
> > > and the VM
> > > "Generation".  For a Generation 2 VM, the framebuffer memory is allocated 
> > > by the
> > > Hyper-V host and is assigned to guest MMIO space. The hyperv_fb driver 
> > > does a
> > > vmalloc() allocation for deferred I/O to work against. This combination 
> > > handles mmap()
> > > of /dev/fb<n> correctly and the performance benefits of deferred I/O are 
> > > substantial.
> > >
> > > But for a Generation 1 VM, the hyperv_fb driver allocates the framebuffer 
> > > memory in
> > > contiguous guest physical memory using alloc_pages() or 
> > > dma_alloc_coherent(), and
> > > informs the Hyper-V host of the location. In this case, mmap() with 
> > > deferred I/O does
> > > not work. The mmap() succeeds, and user space updates to the mmap'ed 
> > > memory are
> > > correctly reflected to the framebuffer. But when the user space program 
> > > does munmap()
> > > or terminates, the Linux kernel free lists become scrambled and the 
> > > kernel eventually
> > > panics. The problem is that when munmap() is done, the PTEs in the VMA 
> > > are cleaned
> > > up, and the corresponding struct page refcounts are decremented. If the 
> > > refcount goes
> > > to zero (which it typically will), the page is immediately freed. In this 
> > > way, some or all
> > > of the framebuffer memory gets erroneously freed. From what I see, the 
> > > VMA should
> > > be marked VM_PFNMAP when allocated memory kernel is being used as the
> > > framebuffer with deferred I/O, but that's not happening. The handling of 
> > > deferred I/O
> > > page faults would also need updating to make this work.

I assume this is triggered by running any fbdev userspace that uses
mmap(), e.g. fbtest?

> > > The fbdev deferred I/O support was originally added to the hyperv_fb 
> > > driver in the
> > > 5.6 kernel, and based on my recent experiments, it has never worked 
> > > correctly when
> > > the framebuffer is allocated from kernel memory. fbdev deferred I/O 
> > > support for using
> > > kernel memory as the framebuffer was originally added in commit 
> > > 37b4837959cb9
> > > back in 2008 in Linux 2.6.29. But I don't see how it ever worked 
> > > properly, unless
> > > changes in generic memory management somehow broke it in the intervening 
> > > years.
> > >
> > > I think I know how to fix all this. But before working on a patch, I 
> > > wanted to check
> > > with the fbdev community to see if this might be a known issue and 
> > > whether there
> > > is any additional insight someone might offer. Thanks for any comments or 
> > > help.
> >
> > I haven't heard of any major deferred-i/o issues since I've jumped into 
> > fbdev
> > maintenance. But you might be right, as I haven't looked much into it yet 
> > and
> > there are just a few drivers using it.
>
> Thanks for the input. In the fbdev directory, there are 9 drivers using 
> deferred I/O.
> Of those, 6 use vmalloc() to allocate the framebuffer, and that path works 
> just fine.
> The other 3 use alloc_pages(), dma_alloc_coherent(), or __get_free_pages(), 
> all of
> which manifest the underlying problem when munmap()'ed.  Those 3 drivers are:
>
> * hyperv_fb.c, which I'm working with
> * sh_mobile_lcdcfb.c
> * ssd1307fb.c

Nowadays sh_mobile_lcdcfb is used only on various SuperH boards
(I have no hardware to test).

sh_mobile_lcdcfb was used on ARM-based SH/R-Mobile SoCs until DT
support was added to the DRM driver for the corresponding hardware.
The platform using it was migrated to DRM in commit 138588e9fa237f97
("ARM: dts: renesas: r8a7740: Add LCDC nodes") in v6.8). At the time
of the conversion, fbtest worked fine with sh_mobile_lcdcfb.

Deferred I/O is also used in DRM drivers for displays that are connected
using I2C or SPI.  Last time I tried the st7735r driver, it worked fine
with fbtest.  That was also on arm32, though.

Gr{oetje,eeting}s,

                        Geert


--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

Reply via email to