Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

drm: Some refactoring and bug fixes to address VM panics #2215

Merged
merged 11 commits into from
Oct 9, 2024

Commits on Oct 9, 2024

  1. Configuration menu
    Copy the full SHA
    3e48e14 View commit details
    Browse the repository at this point in the history
  2. drm: Use RW_SYSINIT instead of implementing the same thing manually

    No functional change intended.
    markjdb committed Oct 9, 2024
    Configuration menu
    Copy the full SHA
    dd7549c View commit details
    Browse the repository at this point in the history
  3. panfrost: Add some assertions

    Make sure that a failure from pmap_gpu_enter() triggers an assertion failure.
    This should only happen under memory pressure.
    markjdb committed Oct 9, 2024
    Configuration menu
    Copy the full SHA
    4128385 View commit details
    Browse the repository at this point in the history
  4. drm: Remove some commented-out code

    mmap_sem refers to a Linux synchronization mechanism.  Linux is different enough
    here that the references are not very helpful.
    
    No functional change intended.
    markjdb committed Oct 9, 2024
    Configuration menu
    Copy the full SHA
    3406952 View commit details
    Browse the repository at this point in the history
  5. drm: Move an assignment closer to initialization

    vm_pfn_pcount is only set once, we might as well set it during
    initialization.
    markjdb committed Oct 9, 2024
    Configuration menu
    Copy the full SHA
    250ac46 View commit details
    Browse the repository at this point in the history
  6. drm: Fix page busy handling

    markjdb committed Oct 9, 2024
    Configuration menu
    Copy the full SHA
    1a484e3 View commit details
    Browse the repository at this point in the history
  7. drm: Fix the size passed to vm_pager_allocate() for SG objects

    vmap->vm_len is always 0 here.  I believe this code is effectively dead, but
    let's fix it anyway.
    markjdb committed Oct 9, 2024
    Configuration menu
    Copy the full SHA
    30ef5dc View commit details
    Browse the repository at this point in the history
  8. drm: Fix use of Mach error numbers in drm_cdev_pager_populate()

    See vm_fault_populate(): a return value of VM_PAGER_BAD tells the fault layer to
    continue handling the fault "normally", i.e., it will allocate a page, insert it
    into the VM object, and map it.  That's not what we want in general.
    markjdb committed Oct 9, 2024
    Configuration menu
    Copy the full SHA
    85890cc View commit details
    Browse the repository at this point in the history
  9. drm: Remove the drm_cdev_pager_fault() implementation

    There are currently no DRM objects of type OBJT_DEVICE, all are of type
    OBJT_PHYS or OBJT_MGTDEVICE.  drm_cdev_pager_fault() is thus dead code, so
    remove it in advance of further refactoring.  In particular, drm_vmap_find()
    will be removed.
    markjdb committed Oct 9, 2024
    Configuration menu
    Copy the full SHA
    db67f1b View commit details
    Browse the repository at this point in the history
  10. phys_pager: Avoid holding the object lock over the pager dtor

    As in dev_pager_dealloc(), drop the object lock around calls to the destructor.
    This might be necessary if the destructor wants to sleep.
    markjdb committed Oct 9, 2024
    Configuration menu
    Copy the full SHA
    aafcf1a View commit details
    Browse the repository at this point in the history
  11. drm: Refactor handling of GEM object mappings

    Each GEM object is backed by a VM object which stores a handle for each page
    belonging to the object.  A GEM object can be mapped multiple times.  Panfrost's
    buffer objects are backed by physical RAM from the host system.
    
    The old code tried to maintain a global list of VMAs which map a GEM object, and
    this used the object pointer as a unique key, which breaks when the same object
    is mapped more than once.  The mapping list is also somewhat awkward to
    maintain: FreeBSD's vm_fault layer is supposed to hide details relating to
    mappings of a given object (for instance, it doesn't pass the fault address to
    DRM), but Linux passes such details, so we end up faking them.
    
    Refactor things to handle the possibility of multiply-mapped GEM objects:
    - Minimize uses of VMAs.  In the pager populate handler, we don't know which
      mapping the fault came from, so it doesn't make sense to try and look up a
      VMA.  In practice, there is no need to know the origin of the fault, we just
      need a pindex to select the page to map.
    - Introduce a struct drm_object_glue, which glues together a GEM object, a VM
      object, and a list of VMAs which map the object.  The list of VMAs is mostly
      useless but I've avoided removing it for now.  Most uses of the VMA are
      replaced by extending the thread-private vm_fault structure.
    - Convert the global linked list lock to an sx lock so that it's possible to
      hold it while allocating memory.
    - Change the DRM object fault interface to avoid referencing VMAs.  This
      deviates from upstream, but the modified code is all quite FreeBSD-specific
      anyway.
    
    While here, fix a related problem: when mmap()ing a device file,
    drm_fstub_do_mmap() tries to infer the VM object type to use.  In particular, it
    creates a "managed device" object for panfrost buffer objects, which isn't
    correct since the object is backed by host RAM.  The problem is further
    illustrated by the need to clear VPO_UNMANAGED and set PG_FICTITIOUS: setting
    PG_FICTITIOUS in host RAM pages is incorrect and can trigger assertion failures
    in the contig reclaim code.
    
    My view is that it's not possible to correctly map DRM objects without modifying
    upstream sources a little bit.  That is, we cannot hide everything in
    drmkpi/linuxkpi.  Keeping this in mind, the change fixes the problem described
    above by adding a new VM object type to struct vm_operations_struct, used in
    drm_fstub_do_mmap() to allocate the correct type of VM object.
    markjdb committed Oct 9, 2024
    Configuration menu
    Copy the full SHA
    57d97fc View commit details
    Browse the repository at this point in the history