• Daniel Vetter's avatar
    drm: add managed resources tied to drm_device · c6603c74
    Daniel Vetter authored
    We have lots of these. And the cleanup code tends to be of dubious
    quality. The biggest wrong pattern is that developers use devm_, which
    ties the release action to the underlying struct device, whereas
    all the userspace visible stuff attached to a drm_device can long
    outlive that one (e.g. after a hotunplug while userspace has open
    files and mmap'ed buffers). Give people what they want, but with more
    correctness.
    
    Mostly copied from devres.c, with types adjusted to fit drm_device and
    a few simplifications - I didn't (yet) copy over everything. Since
    the types don't match code sharing looked like a hopeless endeavour.
    
    For now it's only super simplified, no groups, you can't remove
    actions (but kfree exists, we'll need that soon). Plus all specific to
    drm_device ofc, including the logging. Which I didn't bother to make
    compile-time optional, since none of the other drm logging is compile
    time optional either.
    
    One tricky bit here is the chicken&egg between allocating your
    drm_device structure and initiliazing it with drm_dev_init. For
    perfect onion unwinding we'd need to have the action to kfree the
    allocation registered before drm_dev_init registers any of its own
    release handlers. But drm_dev_init doesn't know where exactly the
    drm_device is emebedded into the overall structure, and by the time it
    returns it'll all be too late. And forcing drivers to be able clean up
    everything except the one kzalloc is silly.
    
    Work around this by having a very special final_kfree pointer. This
    also avoids troubles with the list head possibly disappearing from
    underneath us when we release all resources attached to the
    drm_device.
    
    v2: Do all the kerneldoc at the end, to avoid lots of fairly pointless
    shuffling while getting everything into shape.
    
    v3: Add static to add/del_dr (Neil)
    Move typo fix to the right patch (Neil)
    
    v4: Enforce contract for drmm_add_final_kfree:
    
    Use ksize() to check that the drm_device is indeed contained somewhere
    in the final kfree(). Because we need that or the entire managed
    release logic blows up in a pile of use-after-frees. Motivated by a
    discussion with Laurent.
    
    v5: Review from Laurent:
    - %zu instead of casting size_t
    - header guards
    - sorting of includes
    - guarding of data assignment if we didn't allocate it for a NULL
      pointer
    - delete spurious newline
    - cast void* data parameter correctly in ->release call, no idea how
      this even worked before
    
    v6: Review from Sam
    - Add the kerneldoc for the managed sub-struct back in, even if it
      doesn't show up in the generated html somehow.
    - Explain why __always_inline.
    - Fix bisectability around the final kfree() in drm_dev_relase(). This
      is just interim code which will disappear again.
    - Some whitespace polish.
    - Add debug output when drmm_add_action or drmm_kmalloc fail.
    
    v7: My bisectability fix wasn't up to par as noticed by smatch.
    
    v8: Remove unecessary {} around if else
    
    v9: Use kstrdup_const, which requires kfree_const and introducing a free_dr()
    helper (Thomas).
    
    v10: kfree_const goes boom on the plain "kmalloc" assignment, somehow
    we need to wrap that in kstrdup_const() too!! Also renumber revision
    log, I somehow reset it midway thruh.
    Reviewed-by: default avatarSam Ravnborg <sam@ravnborg.org>
    Cc: Thomas Zimmermann <tzimmermann@suse.de>
    Cc: Dan Carpenter <dan.carpenter@oracle.com>
    Cc: Sam Ravnborg <sam@ravnborg.org>
    Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
    Cc: Neil Armstrong <narmstrong@baylibre.com
    Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Cc: "Rafael J. Wysocki" <rafael@kernel.org>
    Signed-off-by: default avatarDaniel Vetter <daniel.vetter@intel.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20200324124540.3227396-1-daniel.vetter@ffwll.ch
    c6603c74
drm_managed.h 789 Bytes