linuxkpi: a layer device's kobject is initialised and named dev_name() #18
Loading…
Reference in a new issue
No description provided.
Delete branch "x230-lkpi-device-kobject"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
struct deviceembeds a kobject that the layer never initialised: its name was NULL and its reference count zero. Linux'sdevice_initialize()anddev_set_name()leave it initialised and named, and drivers rely on that. i915 hangs kobjects under the DRM minor's device (on illumos the PCI device,lkpi_drm_set_kdev()) and reads its name.On a ThinkPad X230 (HD 4000,
8086:0166), once the display device existed (x230-nodisplay-device), the attach reachedi915_driver_register()and panicked:lkpi_device_init()now initialises the kobject with a ktype that releases nothing (the device's lifetime stayslkpi_refs) and names itdev_name()(0000:00:02.0for PCI devices);lkpi_device_fini()drops that reference andkobject_release()frees the name.Tested on the X230 (branch
x230-test): attach completes,lkpi_warnings0,/dev/dri/card0andrenderD128exist; detach (update_drv -d), unload of i915n, drm_helpers, linuxkpi and drm_core, and a second attach in the same boot all work.Review round 1 fix (
e68810f)The first version let
lkpi_device_fini()drop its reference while a child kobject still pointed at the device (i915 v7.2 never puts theenginedirectory thatintel_engines_add_sysfs()creates under the device), so the device memory was freed under that child and the name leaked. Now:kobject_add()links,kobject_del()unlinks, under one leaf mutex; no allocation, other lock or release while it is held).lkpi_device_fini()orphans remaining children (their parent becomes NULL and the reference each held is dropped), then drops the device's own reference, which frees the name; it warns about extra references and about an over-put.kobject_add()under a parent that was never initialised is-EINVAL.struct kobjectgrew, soLINUXKPI_ABIis 2: linuxkpi, i915n and linuxkpi_selftest must be installed together (a mismatch is refused at_init).linuxkpi/tests/host/t_kobject.c(35 tests, 1138 checks, clang ASan/UBSan and gcc on oibuild), including concurrent add/delete and orphaning racing deletes and puts;st_probeinlinuxkpi_selftestchecks the device kobject's name and child references (not yet run in a guest).-z defs.The X230 run above was at
1b86938; the orphaning path has not run on hardware or in a guest yet.struct device embeds a kobject that the layer never initialised: its name was NULL and its reference count zero. Linux's device_initialize() and dev_set_name() leave it initialised and named, and drivers rely on that. i915 hangs kobjects under the DRM minor's device (on illumos the PCI device, lkpi_drm_set_kdev()) and reads its name. At the first attach on a ThinkPad X230 (HD 4000, 8086:0166) that was: WARNING at linuxkpi/src/lkpi_kobject.c:148: kobject_get: ... not initialised (twice) BAD TRAP: type=e (#pf Page fault) addr=0 occurred in module "unix" due to a NULL pointer dereference strncmp+0x20(0, ..., 2) is_object_gt+0x1d intel_sysfs_rps_init+0x22 intel_gt_sysfs_pm_init+0x14 intel_gt_sysfs_register+0xd5 intel_gt_driver_register+0x40 i915_driver_register+0xb1 i915_driver_probe+0x189 lkpi_device_init() now initialises the kobject with a ktype that releases nothing (the device's lifetime stays lkpi_refs) and names it dev_name() ("0000:00:02.0" for PCI devices); lkpi_device_fini() drops that reference, and kobject_release() frees the name. A kobject still holding the device's as its parent keeps it until it lets go.