Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
Hi Greg, On Wed, Feb 19, 2020 at 07:19:32PM +0100, Greg Kroah-Hartman wrote: > On Wed, Feb 19, 2020 at 07:36:52PM +0200, Laurent Pinchart wrote: > > On Wed, Feb 19, 2020 at 06:00:46PM +0100, Greg Kroah-Hartman wrote: > >> On Wed, Feb 19, 2020 at 03:22:49PM +0100, Daniel Vetter wrote: > >>> On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman wrote: > On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote: > > On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote: > >> 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 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. > > > > This is all a very good idea ! Many subsystems are plagged by drivers > > using devm_k*alloc to allocate data accessible by userspace. Since the > > introduction of devm_*, we've likely reduced the number of memory leaks, > > but I'm pretty sure we've increased the risk of crashes as I've seen > > some drivers that used .release() callbacks correctly being naively > > converted to incorrect devm_* usage :-( > > > > This leads me to a question: if other subsystems have the same problem, > > could we turn this implementation into something more generic ? It > > doesn't have to be done right away and shouldn't block merging this > > series, but I think it would be very useful. > > It shouldn't be that hard to tie this into a drv_m() type of a thing > (driver_memory?) > > And yes, I think it's much better than devm_* for the obvious reasons of > this being needed here. > >>> > >>> There's two reasons I went with copypasta instead of trying to share code: > >>> - Type checking, I definitely don't want people to mix up devm_ with > >>> drmm_. But even if we do a drv_m that subsystems could embed we do > >>> have quite a few different types of component drivers (and with > >>> drm_panel and drm_bridge even standardized), and I don't want people > >>> to be able to pass the wrong kind of struct to e.g. a managed > >>> drmm_connector_init - it really needs to be the drm_device, not a > >>> panel or bridge or something else. > >> > >> Fair enough, that makes sense. > >> > >>> - We could still share the code as a kind of implementation/backend > >>> library. But it's not much, and with embedding I could use the drm > >>> device logging stuff which is kinda nice. But if there's more demand > >>> for this I can definitely see the point in sharing this, as Laurent > >>> pointed out with the tiny optimization with not allocating a NULL void > >>> * that I've done (and screwed up) it's not entirely trivial code. > >> > >> I think moving over time to having this be a backend library is good. > >> But no rush/issues here with this going in now, it solves a real need > >> and we can refactor it later on to try to make it more "bus/class" > >> generic as needed. > > > > >From a type checking point of view, it would then be nice to have a > > structure that models a device node, other than just struct device that > > is shared by all types of devices. As someone who was involve in the > > creation of the device model we have today, and thus know the history, > > what's your
Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
On Wed, Feb 19, 2020 at 7:19 PM Greg Kroah-Hartman wrote: > > On Wed, Feb 19, 2020 at 07:36:52PM +0200, Laurent Pinchart wrote: > > Hi Greg, > > > > On Wed, Feb 19, 2020 at 06:00:46PM +0100, Greg Kroah-Hartman wrote: > > > On Wed, Feb 19, 2020 at 03:22:49PM +0100, Daniel Vetter wrote: > > > > On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman wrote: > > > > > On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote: > > > > > > On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote: > > > > > > > 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 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. > > > > > > > > > > > > This is all a very good idea ! Many subsystems are plagged by > > > > > > drivers > > > > > > using devm_k*alloc to allocate data accessible by userspace. Since > > > > > > the > > > > > > introduction of devm_*, we've likely reduced the number of memory > > > > > > leaks, > > > > > > but I'm pretty sure we've increased the risk of crashes as I've seen > > > > > > some drivers that used .release() callbacks correctly being naively > > > > > > converted to incorrect devm_* usage :-( > > > > > > > > > > > > This leads me to a question: if other subsystems have the same > > > > > > problem, > > > > > > could we turn this implementation into something more generic ? It > > > > > > doesn't have to be done right away and shouldn't block merging this > > > > > > series, but I think it would be very useful. > > > > > > > > > > It shouldn't be that hard to tie this into a drv_m() type of a thing > > > > > (driver_memory?) > > > > > > > > > > And yes, I think it's much better than devm_* for the obvious reasons > > > > > of > > > > > this being needed here. > > > > > > > > There's two reasons I went with copypasta instead of trying to share > > > > code: > > > > - Type checking, I definitely don't want people to mix up devm_ with > > > > drmm_. But even if we do a drv_m that subsystems could embed we do > > > > have quite a few different types of component drivers (and with > > > > drm_panel and drm_bridge even standardized), and I don't want people > > > > to be able to pass the wrong kind of struct to e.g. a managed > > > > drmm_connector_init - it really needs to be the drm_device, not a > > > > panel or bridge or something else. > > > > > > Fair enough, that makes sense. > > > > > > > - We could still share the code as a kind of implementation/backend > > > > library. But it's not much, and with embedding I could use the drm > > > > device logging stuff which is kinda nice. But if there's more demand > > > > for this I can definitely see the point in sharing this, as Laurent > > > > pointed out with the tiny optimization with not allocating a NULL void > > > > * that I've done (and screwed up) it's not entirely trivial code. > > > > > > I think moving over time to having this be a backend library is good. > > >
Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
On Wed, Feb 19, 2020 at 07:36:52PM +0200, Laurent Pinchart wrote: > Hi Greg, > > On Wed, Feb 19, 2020 at 06:00:46PM +0100, Greg Kroah-Hartman wrote: > > On Wed, Feb 19, 2020 at 03:22:49PM +0100, Daniel Vetter wrote: > > > On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman wrote: > > > > On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote: > > > > > On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote: > > > > > > 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 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. > > > > > > > > > > This is all a very good idea ! Many subsystems are plagged by drivers > > > > > using devm_k*alloc to allocate data accessible by userspace. Since the > > > > > introduction of devm_*, we've likely reduced the number of memory > > > > > leaks, > > > > > but I'm pretty sure we've increased the risk of crashes as I've seen > > > > > some drivers that used .release() callbacks correctly being naively > > > > > converted to incorrect devm_* usage :-( > > > > > > > > > > This leads me to a question: if other subsystems have the same > > > > > problem, > > > > > could we turn this implementation into something more generic ? It > > > > > doesn't have to be done right away and shouldn't block merging this > > > > > series, but I think it would be very useful. > > > > > > > > It shouldn't be that hard to tie this into a drv_m() type of a thing > > > > (driver_memory?) > > > > > > > > And yes, I think it's much better than devm_* for the obvious reasons of > > > > this being needed here. > > > > > > There's two reasons I went with copypasta instead of trying to share code: > > > - Type checking, I definitely don't want people to mix up devm_ with > > > drmm_. But even if we do a drv_m that subsystems could embed we do > > > have quite a few different types of component drivers (and with > > > drm_panel and drm_bridge even standardized), and I don't want people > > > to be able to pass the wrong kind of struct to e.g. a managed > > > drmm_connector_init - it really needs to be the drm_device, not a > > > panel or bridge or something else. > > > > Fair enough, that makes sense. > > > > > - We could still share the code as a kind of implementation/backend > > > library. But it's not much, and with embedding I could use the drm > > > device logging stuff which is kinda nice. But if there's more demand > > > for this I can definitely see the point in sharing this, as Laurent > > > pointed out with the tiny optimization with not allocating a NULL void > > > * that I've done (and screwed up) it's not entirely trivial code. > > > > I think moving over time to having this be a backend library is good. > > But no rush/issues here with this going in now, it solves a real need > > and we can refactor it later on to try to make it more "bus/class" > > generic as needed. > > >From a type checking point of view, it would then be nice to have a > structure that models a device node, other than just struct device that > is
Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
Hi Greg, On Wed, Feb 19, 2020 at 06:00:46PM +0100, Greg Kroah-Hartman wrote: > On Wed, Feb 19, 2020 at 03:22:49PM +0100, Daniel Vetter wrote: > > On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman wrote: > > > On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote: > > > > On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote: > > > > > 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 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. > > > > > > > > This is all a very good idea ! Many subsystems are plagged by drivers > > > > using devm_k*alloc to allocate data accessible by userspace. Since the > > > > introduction of devm_*, we've likely reduced the number of memory leaks, > > > > but I'm pretty sure we've increased the risk of crashes as I've seen > > > > some drivers that used .release() callbacks correctly being naively > > > > converted to incorrect devm_* usage :-( > > > > > > > > This leads me to a question: if other subsystems have the same problem, > > > > could we turn this implementation into something more generic ? It > > > > doesn't have to be done right away and shouldn't block merging this > > > > series, but I think it would be very useful. > > > > > > It shouldn't be that hard to tie this into a drv_m() type of a thing > > > (driver_memory?) > > > > > > And yes, I think it's much better than devm_* for the obvious reasons of > > > this being needed here. > > > > There's two reasons I went with copypasta instead of trying to share code: > > - Type checking, I definitely don't want people to mix up devm_ with > > drmm_. But even if we do a drv_m that subsystems could embed we do > > have quite a few different types of component drivers (and with > > drm_panel and drm_bridge even standardized), and I don't want people > > to be able to pass the wrong kind of struct to e.g. a managed > > drmm_connector_init - it really needs to be the drm_device, not a > > panel or bridge or something else. > > Fair enough, that makes sense. > > > - We could still share the code as a kind of implementation/backend > > library. But it's not much, and with embedding I could use the drm > > device logging stuff which is kinda nice. But if there's more demand > > for this I can definitely see the point in sharing this, as Laurent > > pointed out with the tiny optimization with not allocating a NULL void > > * that I've done (and screwed up) it's not entirely trivial code. > > I think moving over time to having this be a backend library is good. > But no rush/issues here with this going in now, it solves a real need > and we can refactor it later on to try to make it more "bus/class" > generic as needed. >From a type checking point of view, it would then be nice to have a structure that models a device node, other than just struct device that is shared by all types of devices. As someone who was involve in the creation of the device model we have today, and thus know the history, what's your opinion on that ? -- Regards, Laurent Pinchart ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org
Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
On Wed, Feb 19, 2020 at 6:02 PM Laurent Pinchart wrote: > > Hi Daniel, > > On Wed, Feb 19, 2020 at 05:53:59PM +0100, Daniel Vetter wrote: > > On Wed, Feb 19, 2020 at 5:46 PM Laurent Pinchart wrote: > > > On Wed, Feb 19, 2020 at 05:22:38PM +0100, Daniel Vetter wrote: > > >> On Wed, Feb 19, 2020 at 5:09 PM Emil Velikov wrote: > > >>> On Wed, 19 Feb 2020 at 14:23, Daniel Vetter wrote: > > On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman wrote: > > > On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote: > > >> On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote: > > >>> 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 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. > > >> > > >> This is all a very good idea ! Many subsystems are plagged by drivers > > >> using devm_k*alloc to allocate data accessible by userspace. Since > > >> the > > >> introduction of devm_*, we've likely reduced the number of memory > > >> leaks, > > >> but I'm pretty sure we've increased the risk of crashes as I've seen > > >> some drivers that used .release() callbacks correctly being naively > > >> converted to incorrect devm_* usage :-( > > >> > > >> This leads me to a question: if other subsystems have the same > > >> problem, > > >> could we turn this implementation into something more generic ? It > > >> doesn't have to be done right away and shouldn't block merging this > > >> series, but I think it would be very useful. > > > > > > It shouldn't be that hard to tie this into a drv_m() type of a thing > > > (driver_memory?) > > > > > > And yes, I think it's much better than devm_* for the obvious reasons > > > of > > > this being needed here. > > > > There's two reasons I went with copypasta instead of trying to share > > code: > > - Type checking, I definitely don't want people to mix up devm_ with > > drmm_. But even if we do a drv_m that subsystems could embed we do > > have quite a few different types of component drivers (and with > > drm_panel and drm_bridge even standardized), and I don't want people > > to be able to pass the wrong kind of struct to e.g. a managed > > drmm_connector_init - it really needs to be the drm_device, not a > > panel or bridge or something else. > > > > - We could still share the code as a kind of implementation/backend > > library. But it's not much, and with embedding I could use the drm > > device logging stuff which is kinda nice. But if there's more demand > > for this I can definitely see the point in sharing this, as Laurent > > pointed out with the tiny optimization with not allocating a NULL void > > * that I've done (and screwed up) it's not entirely trivial code. > > >>> > > >>> My 2c as they say, although closer to a brain dump :-) > > >>> > > >>> On one hand the drm_device has an embedded struct device. On the other > >
Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
Hi Daniel, On Wed, Feb 19, 2020 at 05:53:59PM +0100, Daniel Vetter wrote: > On Wed, Feb 19, 2020 at 5:46 PM Laurent Pinchart wrote: > > On Wed, Feb 19, 2020 at 05:22:38PM +0100, Daniel Vetter wrote: > >> On Wed, Feb 19, 2020 at 5:09 PM Emil Velikov wrote: > >>> On Wed, 19 Feb 2020 at 14:23, Daniel Vetter wrote: > On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman wrote: > > On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote: > >> On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote: > >>> 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 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. > >> > >> This is all a very good idea ! Many subsystems are plagged by drivers > >> using devm_k*alloc to allocate data accessible by userspace. Since the > >> introduction of devm_*, we've likely reduced the number of memory > >> leaks, > >> but I'm pretty sure we've increased the risk of crashes as I've seen > >> some drivers that used .release() callbacks correctly being naively > >> converted to incorrect devm_* usage :-( > >> > >> This leads me to a question: if other subsystems have the same problem, > >> could we turn this implementation into something more generic ? It > >> doesn't have to be done right away and shouldn't block merging this > >> series, but I think it would be very useful. > > > > It shouldn't be that hard to tie this into a drv_m() type of a thing > > (driver_memory?) > > > > And yes, I think it's much better than devm_* for the obvious reasons of > > this being needed here. > > There's two reasons I went with copypasta instead of trying to share > code: > - Type checking, I definitely don't want people to mix up devm_ with > drmm_. But even if we do a drv_m that subsystems could embed we do > have quite a few different types of component drivers (and with > drm_panel and drm_bridge even standardized), and I don't want people > to be able to pass the wrong kind of struct to e.g. a managed > drmm_connector_init - it really needs to be the drm_device, not a > panel or bridge or something else. > > - We could still share the code as a kind of implementation/backend > library. But it's not much, and with embedding I could use the drm > device logging stuff which is kinda nice. But if there's more demand > for this I can definitely see the point in sharing this, as Laurent > pointed out with the tiny optimization with not allocating a NULL void > * that I've done (and screwed up) it's not entirely trivial code. > >>> > >>> My 2c as they say, although closer to a brain dump :-) > >>> > >>> On one hand the drm_device has an embedded struct device. On the other > >>> drm_device preserves state which outlives the embedded struct device. > >>> > >>> Would it make sense to keep drm_device better related to the > >>> underlying device? Effectively moving the $misc state to drm_driver. > >>> This idea does raise another question - struct drm_driver unlike many > >>> other struct $foo_driver, does not embedded
Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
On Wed, Feb 19, 2020 at 03:22:49PM +0100, Daniel Vetter wrote: > On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman > wrote: > > > > On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote: > > > Hi Daniel, > > > > > > Thank you for the patch. > > > > > > On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote: > > > > 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 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. > > > > > > This is all a very good idea ! Many subsystems are plagged by drivers > > > using devm_k*alloc to allocate data accessible by userspace. Since the > > > introduction of devm_*, we've likely reduced the number of memory leaks, > > > but I'm pretty sure we've increased the risk of crashes as I've seen > > > some drivers that used .release() callbacks correctly being naively > > > converted to incorrect devm_* usage :-( > > > > > > This leads me to a question: if other subsystems have the same problem, > > > could we turn this implementation into something more generic ? It > > > doesn't have to be done right away and shouldn't block merging this > > > series, but I think it would be very useful. > > > > It shouldn't be that hard to tie this into a drv_m() type of a thing > > (driver_memory?) > > > > And yes, I think it's much better than devm_* for the obvious reasons of > > this being needed here. > > There's two reasons I went with copypasta instead of trying to share code: > - Type checking, I definitely don't want people to mix up devm_ with > drmm_. But even if we do a drv_m that subsystems could embed we do > have quite a few different types of component drivers (and with > drm_panel and drm_bridge even standardized), and I don't want people > to be able to pass the wrong kind of struct to e.g. a managed > drmm_connector_init - it really needs to be the drm_device, not a > panel or bridge or something else. Fair enough, that makes sense. > - We could still share the code as a kind of implementation/backend > library. But it's not much, and with embedding I could use the drm > device logging stuff which is kinda nice. But if there's more demand > for this I can definitely see the point in sharing this, as Laurent > pointed out with the tiny optimization with not allocating a NULL void > * that I've done (and screwed up) it's not entirely trivial code. I think moving over time to having this be a backend library is good. But no rush/issues here with this going in now, it solves a real need and we can refactor it later on to try to make it more "bus/class" generic as needed. thanks, greg k-h ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
On Wed, Feb 19, 2020 at 5:46 PM Laurent Pinchart wrote: > > Hi Daniel, > > On Wed, Feb 19, 2020 at 05:22:38PM +0100, Daniel Vetter wrote: > > On Wed, Feb 19, 2020 at 5:09 PM Emil Velikov wrote: > > > On Wed, 19 Feb 2020 at 14:23, Daniel Vetter wrote: > > >> On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman wrote: > > >>> On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote: > > On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote: > > > 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 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. > > > > This is all a very good idea ! Many subsystems are plagged by drivers > > using devm_k*alloc to allocate data accessible by userspace. Since the > > introduction of devm_*, we've likely reduced the number of memory > > leaks, > > but I'm pretty sure we've increased the risk of crashes as I've seen > > some drivers that used .release() callbacks correctly being naively > > converted to incorrect devm_* usage :-( > > > > This leads me to a question: if other subsystems have the same problem, > > could we turn this implementation into something more generic ? It > > doesn't have to be done right away and shouldn't block merging this > > series, but I think it would be very useful. > > >>> > > >>> It shouldn't be that hard to tie this into a drv_m() type of a thing > > >>> (driver_memory?) > > >>> > > >>> And yes, I think it's much better than devm_* for the obvious reasons of > > >>> this being needed here. > > >> > > >> There's two reasons I went with copypasta instead of trying to share > > >> code: > > >> - Type checking, I definitely don't want people to mix up devm_ with > > >> drmm_. But even if we do a drv_m that subsystems could embed we do > > >> have quite a few different types of component drivers (and with > > >> drm_panel and drm_bridge even standardized), and I don't want people > > >> to be able to pass the wrong kind of struct to e.g. a managed > > >> drmm_connector_init - it really needs to be the drm_device, not a > > >> panel or bridge or something else. > > >> > > >> - We could still share the code as a kind of implementation/backend > > >> library. But it's not much, and with embedding I could use the drm > > >> device logging stuff which is kinda nice. But if there's more demand > > >> for this I can definitely see the point in sharing this, as Laurent > > >> pointed out with the tiny optimization with not allocating a NULL void > > >> * that I've done (and screwed up) it's not entirely trivial code. > > > > > > My 2c as they say, although closer to a brain dump :-) > > > > > > On one hand the drm_device has an embedded struct device. On the other > > > drm_device preserves state which outlives the embedded struct device. > > > > > > Would it make sense to keep drm_device better related to the > > > underlying device? Effectively moving the $misc state to drm_driver. > > > This idea does raise another question - struct drm_driver unlike many > > > other struct $foo_driver, does not embedded device_driver :-( > > > So if one is to cover the above two,
Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
Hi Daniel, On Wed, Feb 19, 2020 at 05:22:38PM +0100, Daniel Vetter wrote: > On Wed, Feb 19, 2020 at 5:09 PM Emil Velikov wrote: > > On Wed, 19 Feb 2020 at 14:23, Daniel Vetter wrote: > >> On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman wrote: > >>> On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote: > On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote: > > 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 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. > > This is all a very good idea ! Many subsystems are plagged by drivers > using devm_k*alloc to allocate data accessible by userspace. Since the > introduction of devm_*, we've likely reduced the number of memory leaks, > but I'm pretty sure we've increased the risk of crashes as I've seen > some drivers that used .release() callbacks correctly being naively > converted to incorrect devm_* usage :-( > > This leads me to a question: if other subsystems have the same problem, > could we turn this implementation into something more generic ? It > doesn't have to be done right away and shouldn't block merging this > series, but I think it would be very useful. > >>> > >>> It shouldn't be that hard to tie this into a drv_m() type of a thing > >>> (driver_memory?) > >>> > >>> And yes, I think it's much better than devm_* for the obvious reasons of > >>> this being needed here. > >> > >> There's two reasons I went with copypasta instead of trying to share code: > >> - Type checking, I definitely don't want people to mix up devm_ with > >> drmm_. But even if we do a drv_m that subsystems could embed we do > >> have quite a few different types of component drivers (and with > >> drm_panel and drm_bridge even standardized), and I don't want people > >> to be able to pass the wrong kind of struct to e.g. a managed > >> drmm_connector_init - it really needs to be the drm_device, not a > >> panel or bridge or something else. > >> > >> - We could still share the code as a kind of implementation/backend > >> library. But it's not much, and with embedding I could use the drm > >> device logging stuff which is kinda nice. But if there's more demand > >> for this I can definitely see the point in sharing this, as Laurent > >> pointed out with the tiny optimization with not allocating a NULL void > >> * that I've done (and screwed up) it's not entirely trivial code. > > > > My 2c as they say, although closer to a brain dump :-) > > > > On one hand the drm_device has an embedded struct device. On the other > > drm_device preserves state which outlives the embedded struct device. > > > > Would it make sense to keep drm_device better related to the > > underlying device? Effectively moving the $misc state to drm_driver. > > This idea does raise another question - struct drm_driver unlike many > > other struct $foo_driver, does not embedded device_driver :-( > > So if one is to cover the above two, then the embedding concerns will > > be elevated. > > drm_driver isn't a bus device driver in the linux driver model sense, > but an uapi thing that sits on top of some underlying device. So maybe > better to rename drm_driver to
Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
On Wed, 19 Feb 2020 at 16:22, Daniel Vetter wrote: > > On Wed, Feb 19, 2020 at 5:09 PM Emil Velikov wrote: > > > > On Wed, 19 Feb 2020 at 14:23, Daniel Vetter wrote: > > > > > > On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman > > > wrote: > > > > > > > > On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote: > > > > > Hi Daniel, > > > > > > > > > > Thank you for the patch. > > > > > > > > > > On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote: > > > > > > 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 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. > > > > > > > > > > This is all a very good idea ! Many subsystems are plagged by drivers > > > > > using devm_k*alloc to allocate data accessible by userspace. Since the > > > > > introduction of devm_*, we've likely reduced the number of memory > > > > > leaks, > > > > > but I'm pretty sure we've increased the risk of crashes as I've seen > > > > > some drivers that used .release() callbacks correctly being naively > > > > > converted to incorrect devm_* usage :-( > > > > > > > > > > This leads me to a question: if other subsystems have the same > > > > > problem, > > > > > could we turn this implementation into something more generic ? It > > > > > doesn't have to be done right away and shouldn't block merging this > > > > > series, but I think it would be very useful. > > > > > > > > It shouldn't be that hard to tie this into a drv_m() type of a thing > > > > (driver_memory?) > > > > > > > > And yes, I think it's much better than devm_* for the obvious reasons of > > > > this being needed here. > > > > > > There's two reasons I went with copypasta instead of trying to share code: > > > - Type checking, I definitely don't want people to mix up devm_ with > > > drmm_. But even if we do a drv_m that subsystems could embed we do > > > have quite a few different types of component drivers (and with > > > drm_panel and drm_bridge even standardized), and I don't want people > > > to be able to pass the wrong kind of struct to e.g. a managed > > > drmm_connector_init - it really needs to be the drm_device, not a > > > panel or bridge or something else. > > > > > > - We could still share the code as a kind of implementation/backend > > > library. But it's not much, and with embedding I could use the drm > > > device logging stuff which is kinda nice. But if there's more demand > > > for this I can definitely see the point in sharing this, as Laurent > > > pointed out with the tiny optimization with not allocating a NULL void > > > * that I've done (and screwed up) it's not entirely trivial code. > > > > > > > My 2c as they say, although closer to a brain dump :-) > > > > On one hand the drm_device has an embedded struct device. On the other > > drm_device preserves state which outlives the embedded struct device. > > > > Would it make sense to keep drm_device better related to the > > underlying device? Effectively moving the $misc state to drm_driver. > > This idea does raise
Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
On Wed, Feb 19, 2020 at 5:09 PM Emil Velikov wrote: > > On Wed, 19 Feb 2020 at 14:23, Daniel Vetter wrote: > > > > On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman > > wrote: > > > > > > On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote: > > > > Hi Daniel, > > > > > > > > Thank you for the patch. > > > > > > > > On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote: > > > > > 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 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. > > > > > > > > This is all a very good idea ! Many subsystems are plagged by drivers > > > > using devm_k*alloc to allocate data accessible by userspace. Since the > > > > introduction of devm_*, we've likely reduced the number of memory leaks, > > > > but I'm pretty sure we've increased the risk of crashes as I've seen > > > > some drivers that used .release() callbacks correctly being naively > > > > converted to incorrect devm_* usage :-( > > > > > > > > This leads me to a question: if other subsystems have the same problem, > > > > could we turn this implementation into something more generic ? It > > > > doesn't have to be done right away and shouldn't block merging this > > > > series, but I think it would be very useful. > > > > > > It shouldn't be that hard to tie this into a drv_m() type of a thing > > > (driver_memory?) > > > > > > And yes, I think it's much better than devm_* for the obvious reasons of > > > this being needed here. > > > > There's two reasons I went with copypasta instead of trying to share code: > > - Type checking, I definitely don't want people to mix up devm_ with > > drmm_. But even if we do a drv_m that subsystems could embed we do > > have quite a few different types of component drivers (and with > > drm_panel and drm_bridge even standardized), and I don't want people > > to be able to pass the wrong kind of struct to e.g. a managed > > drmm_connector_init - it really needs to be the drm_device, not a > > panel or bridge or something else. > > > > - We could still share the code as a kind of implementation/backend > > library. But it's not much, and with embedding I could use the drm > > device logging stuff which is kinda nice. But if there's more demand > > for this I can definitely see the point in sharing this, as Laurent > > pointed out with the tiny optimization with not allocating a NULL void > > * that I've done (and screwed up) it's not entirely trivial code. > > > > My 2c as they say, although closer to a brain dump :-) > > On one hand the drm_device has an embedded struct device. On the other > drm_device preserves state which outlives the embedded struct device. > > Would it make sense to keep drm_device better related to the > underlying device? Effectively moving the $misc state to drm_driver. > This idea does raise another question - struct drm_driver unlike many > other struct $foo_driver, does not embedded device_driver :-( > So if one is to cover the above two, then the embedding concerns will > be elevated. drm_driver isn't a bus device driver in the linux driver model sense, but an uapi thing that sits on top of some underlying device. So maybe better
Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
On Wed, 19 Feb 2020 at 14:23, Daniel Vetter wrote: > > On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman > wrote: > > > > On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote: > > > Hi Daniel, > > > > > > Thank you for the patch. > > > > > > On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote: > > > > 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 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. > > > > > > This is all a very good idea ! Many subsystems are plagged by drivers > > > using devm_k*alloc to allocate data accessible by userspace. Since the > > > introduction of devm_*, we've likely reduced the number of memory leaks, > > > but I'm pretty sure we've increased the risk of crashes as I've seen > > > some drivers that used .release() callbacks correctly being naively > > > converted to incorrect devm_* usage :-( > > > > > > This leads me to a question: if other subsystems have the same problem, > > > could we turn this implementation into something more generic ? It > > > doesn't have to be done right away and shouldn't block merging this > > > series, but I think it would be very useful. > > > > It shouldn't be that hard to tie this into a drv_m() type of a thing > > (driver_memory?) > > > > And yes, I think it's much better than devm_* for the obvious reasons of > > this being needed here. > > There's two reasons I went with copypasta instead of trying to share code: > - Type checking, I definitely don't want people to mix up devm_ with > drmm_. But even if we do a drv_m that subsystems could embed we do > have quite a few different types of component drivers (and with > drm_panel and drm_bridge even standardized), and I don't want people > to be able to pass the wrong kind of struct to e.g. a managed > drmm_connector_init - it really needs to be the drm_device, not a > panel or bridge or something else. > > - We could still share the code as a kind of implementation/backend > library. But it's not much, and with embedding I could use the drm > device logging stuff which is kinda nice. But if there's more demand > for this I can definitely see the point in sharing this, as Laurent > pointed out with the tiny optimization with not allocating a NULL void > * that I've done (and screwed up) it's not entirely trivial code. > My 2c as they say, although closer to a brain dump :-) On one hand the drm_device has an embedded struct device. On the other drm_device preserves state which outlives the embedded struct device. Would it make sense to keep drm_device better related to the underlying device? Effectively moving the $misc state to drm_driver. This idea does raise another question - struct drm_driver unlike many other struct $foo_driver, does not embedded device_driver :-( So if one is to cover the above two, then the embedding concerns will be elevated. WRT type safety, with the embedded work sorted, one could introduce trivial helpers for drmm_connector_init and friends. In another email you've also raised the question of API diversity and reviews, I believe. IMHO one could start with a bare minimum set and extend as needed. Based on the prompt response from Greg, I suspect review won't be an issue. If people agree with
Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
On Wed, Feb 19, 2020 at 2:33 PM Greg Kroah-Hartman wrote: > > On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote: > > Hi Daniel, > > > > Thank you for the patch. > > > > On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote: > > > 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 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. > > > > This is all a very good idea ! Many subsystems are plagged by drivers > > using devm_k*alloc to allocate data accessible by userspace. Since the > > introduction of devm_*, we've likely reduced the number of memory leaks, > > but I'm pretty sure we've increased the risk of crashes as I've seen > > some drivers that used .release() callbacks correctly being naively > > converted to incorrect devm_* usage :-( > > > > This leads me to a question: if other subsystems have the same problem, > > could we turn this implementation into something more generic ? It > > doesn't have to be done right away and shouldn't block merging this > > series, but I think it would be very useful. > > It shouldn't be that hard to tie this into a drv_m() type of a thing > (driver_memory?) > > And yes, I think it's much better than devm_* for the obvious reasons of > this being needed here. There's two reasons I went with copypasta instead of trying to share code: - Type checking, I definitely don't want people to mix up devm_ with drmm_. But even if we do a drv_m that subsystems could embed we do have quite a few different types of component drivers (and with drm_panel and drm_bridge even standardized), and I don't want people to be able to pass the wrong kind of struct to e.g. a managed drmm_connector_init - it really needs to be the drm_device, not a panel or bridge or something else. - We could still share the code as a kind of implementation/backend library. But it's not much, and with embedding I could use the drm device logging stuff which is kinda nice. But if there's more demand for this I can definitely see the point in sharing this, as Laurent pointed out with the tiny optimization with not allocating a NULL void * that I've done (and screwed up) it's not entirely trivial code. Cheers, Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
On Wed, Feb 19, 2020 at 2:29 PM Laurent Pinchart wrote: > > Hi Daniel, > > Thank you for the patch. > > On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote: > > 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 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. > > This is all a very good idea ! Many subsystems are plagged by drivers > using devm_k*alloc to allocate data accessible by userspace. Since the > introduction of devm_*, we've likely reduced the number of memory leaks, > but I'm pretty sure we've increased the risk of crashes as I've seen > some drivers that used .release() callbacks correctly being naively > converted to incorrect devm_* usage :-( > > This leads me to a question: if other subsystems have the same problem, > could we turn this implementation into something more generic ? It > doesn't have to be done right away and shouldn't block merging this > series, but I think it would be very useful. That's why I'm cc'ing devres maintainers (Greg for driver core) on this. I do think we should make this distinct from devm, with distinct types, so that the compiler can help us catch bugs, and it's easier to spot mistakes in review (in cases where both variants exists, e.g. devm_kzalloc and drmm_kzalloc). Disjoint examples would be devm_ioremap (iounmap only on the final drm_dev_put is a bug) or drmm_connector_init (release the drm_connector already at device driver unbind with devres is a bug). > > v2: Do all the kerneldoc at the end, to avoid lots of fairly pointless > > shuffling while getting everything into shape. > > > > Cc: Greg Kroah-Hartman > > Cc: "Rafael J. Wysocki" > > Signed-off-by: Daniel Vetter > > --- > > Documentation/gpu/drm-internals.rst | 6 + > > drivers/gpu/drm/Makefile| 3 +- > > drivers/gpu/drm/drm_drv.c | 13 ++- > > drivers/gpu/drm/drm_internal.h | 3 + > > drivers/gpu/drm/drm_managed.c | 173 > > include/drm/drm_device.h| 12 ++ > > include/drm/drm_managed.h | 25 > > include/drm/drm_print.h | 6 + > > 8 files changed, 239 insertions(+), 2 deletions(-) > > create mode 100644 drivers/gpu/drm/drm_managed.c > > create mode 100644 include/drm/drm_managed.h > > > > diff --git a/Documentation/gpu/drm-internals.rst > > b/Documentation/gpu/drm-internals.rst > > index a73320576ca9..a6b6145fda78 100644 > > --- a/Documentation/gpu/drm-internals.rst > > +++ b/Documentation/gpu/drm-internals.rst > > @@ -132,6 +132,12 @@ be unmapped; on many devices, the ROM address decoder > > is shared with > > other BARs, so leaving it mapped could cause undesired behaviour like > > hangs or memory corruption. > > > > +Managed Resources > > +- > > + > > +.. kernel-doc:: drivers/gpu/drm/drm_managed.c > > + :doc: managed resources > > + > > Bus-specific Device Registration and PCI Support > > > > > > diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile > > index ca0ca775d37f..53d8fa170143 100644 > > --- a/drivers/gpu/drm/Makefile > > +++ b/drivers/gpu/drm/Makefile > > @@ -17,7 +17,8 @@ drm-y := drm_auth.o drm_cache.o \ > > drm_plane.o drm_color_mgmt.o drm_print.o \ > > drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \ > >
Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
On Wed, Feb 19, 2020 at 03:28:47PM +0200, Laurent Pinchart wrote: > Hi Daniel, > > Thank you for the patch. > > On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote: > > 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 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. > > This is all a very good idea ! Many subsystems are plagged by drivers > using devm_k*alloc to allocate data accessible by userspace. Since the > introduction of devm_*, we've likely reduced the number of memory leaks, > but I'm pretty sure we've increased the risk of crashes as I've seen > some drivers that used .release() callbacks correctly being naively > converted to incorrect devm_* usage :-( > > This leads me to a question: if other subsystems have the same problem, > could we turn this implementation into something more generic ? It > doesn't have to be done right away and shouldn't block merging this > series, but I think it would be very useful. It shouldn't be that hard to tie this into a drv_m() type of a thing (driver_memory?) And yes, I think it's much better than devm_* for the obvious reasons of this being needed here. thanks, greg k-h ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
Hi Daniel, Thank you for the patch. On Wed, Feb 19, 2020 at 11:20:33AM +0100, Daniel Vetter wrote: > 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 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. This is all a very good idea ! Many subsystems are plagged by drivers using devm_k*alloc to allocate data accessible by userspace. Since the introduction of devm_*, we've likely reduced the number of memory leaks, but I'm pretty sure we've increased the risk of crashes as I've seen some drivers that used .release() callbacks correctly being naively converted to incorrect devm_* usage :-( This leads me to a question: if other subsystems have the same problem, could we turn this implementation into something more generic ? It doesn't have to be done right away and shouldn't block merging this series, but I think it would be very useful. > v2: Do all the kerneldoc at the end, to avoid lots of fairly pointless > shuffling while getting everything into shape. > > Cc: Greg Kroah-Hartman > Cc: "Rafael J. Wysocki" > Signed-off-by: Daniel Vetter > --- > Documentation/gpu/drm-internals.rst | 6 + > drivers/gpu/drm/Makefile| 3 +- > drivers/gpu/drm/drm_drv.c | 13 ++- > drivers/gpu/drm/drm_internal.h | 3 + > drivers/gpu/drm/drm_managed.c | 173 > include/drm/drm_device.h| 12 ++ > include/drm/drm_managed.h | 25 > include/drm/drm_print.h | 6 + > 8 files changed, 239 insertions(+), 2 deletions(-) > create mode 100644 drivers/gpu/drm/drm_managed.c > create mode 100644 include/drm/drm_managed.h > > diff --git a/Documentation/gpu/drm-internals.rst > b/Documentation/gpu/drm-internals.rst > index a73320576ca9..a6b6145fda78 100644 > --- a/Documentation/gpu/drm-internals.rst > +++ b/Documentation/gpu/drm-internals.rst > @@ -132,6 +132,12 @@ be unmapped; on many devices, the ROM address decoder is > shared with > other BARs, so leaving it mapped could cause undesired behaviour like > hangs or memory corruption. > > +Managed Resources > +- > + > +.. kernel-doc:: drivers/gpu/drm/drm_managed.c > + :doc: managed resources > + > Bus-specific Device Registration and PCI Support > > > diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile > index ca0ca775d37f..53d8fa170143 100644 > --- a/drivers/gpu/drm/Makefile > +++ b/drivers/gpu/drm/Makefile > @@ -17,7 +17,8 @@ drm-y := drm_auth.o drm_cache.o \ > drm_plane.o drm_color_mgmt.o drm_print.o \ > drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \ > drm_syncobj.o drm_lease.o drm_writeback.o drm_client.o \ > - drm_client_modeset.o drm_atomic_uapi.o drm_hdcp.o > + drm_client_modeset.o drm_atomic_uapi.o drm_hdcp.o \ > + drm_managed.o > > drm-$(CONFIG_DRM_LEGACY) += drm_legacy_misc.o drm_bufs.o drm_context.o > drm_dma.o drm_scatter.o drm_lock.o > drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o > diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c > index 9fcd6ab3c154..3e5627d6eba6 100644 > --- a/drivers/gpu/drm/drm_drv.c > +++ b/drivers/gpu/drm/drm_drv.c > @@ -629,6 +629,9 @@ int drm_dev_init(struct drm_device *dev, > dev->dev = get_device(parent); > dev->driver = driver; > > +
Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
On Wed, Feb 19, 2020 at 1:31 PM Neil Armstrong wrote: > > Hi, > > On 19/02/2020 11:20, Daniel Vetter wrote: > > 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 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. > > > > Cc: Greg Kroah-Hartman > > Cc: "Rafael J. Wysocki" > > Signed-off-by: Daniel Vetter > > --- > > Documentation/gpu/drm-internals.rst | 6 + > > drivers/gpu/drm/Makefile| 3 +- > > drivers/gpu/drm/drm_drv.c | 13 ++- > > drivers/gpu/drm/drm_internal.h | 3 + > > drivers/gpu/drm/drm_managed.c | 173 > > include/drm/drm_device.h| 12 ++ > > include/drm/drm_managed.h | 25 > > include/drm/drm_print.h | 6 + > > 8 files changed, 239 insertions(+), 2 deletions(-) > > create mode 100644 drivers/gpu/drm/drm_managed.c > > create mode 100644 include/drm/drm_managed.h > > > > diff --git a/Documentation/gpu/drm-internals.rst > > b/Documentation/gpu/drm-internals.rst > > index a73320576ca9..a6b6145fda78 100644 > > --- a/Documentation/gpu/drm-internals.rst > > +++ b/Documentation/gpu/drm-internals.rst > > @@ -132,6 +132,12 @@ be unmapped; on many devices, the ROM address decoder > > is shared with > > other BARs, so leaving it mapped could cause undesired behaviour like > > hangs or memory corruption. > > > > +Managed Resources > > +- > > + > > +.. kernel-doc:: drivers/gpu/drm/drm_managed.c > > + :doc: managed resources > > + > > Bus-specific Device Registration and PCI Support > > > > > > diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile > > index ca0ca775d37f..53d8fa170143 100644 > > --- a/drivers/gpu/drm/Makefile > > +++ b/drivers/gpu/drm/Makefile > > @@ -17,7 +17,8 @@ drm-y := drm_auth.o drm_cache.o \ > > drm_plane.o drm_color_mgmt.o drm_print.o \ > > drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \ > > drm_syncobj.o drm_lease.o drm_writeback.o drm_client.o \ > > - drm_client_modeset.o drm_atomic_uapi.o drm_hdcp.o > > + drm_client_modeset.o drm_atomic_uapi.o drm_hdcp.o \ > > + drm_managed.o > > > > drm-$(CONFIG_DRM_LEGACY) += drm_legacy_misc.o drm_bufs.o drm_context.o > > drm_dma.o drm_scatter.o drm_lock.o > > drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o > > diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c > > index 9fcd6ab3c154..3e5627d6eba6 100644 > > --- a/drivers/gpu/drm/drm_drv.c > > +++ b/drivers/gpu/drm/drm_drv.c > > @@ -629,6 +629,9 @@ int drm_dev_init(struct drm_device *dev, > > dev->dev = get_device(parent); > > dev->driver = driver; > > > > + INIT_LIST_HEAD(>managed.resources); > > + spin_lock_init(>managed.lock); > > + > > /* no per-device feature limits by default */ > > dev->driver_features = ~0u; > > > > @@ -828,8 +831,16 @@ static void drm_dev_release(struct kref *ref) > > dev->driver->release(dev); > > } else { > > drm_dev_fini(dev); > > - kfree(dev); > > + if (!dev->managed.final_kfree) { > > +
Re: [Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
Hi, On 19/02/2020 11:20, Daniel Vetter wrote: > 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 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. > > Cc: Greg Kroah-Hartman > Cc: "Rafael J. Wysocki" > Signed-off-by: Daniel Vetter > --- > Documentation/gpu/drm-internals.rst | 6 + > drivers/gpu/drm/Makefile| 3 +- > drivers/gpu/drm/drm_drv.c | 13 ++- > drivers/gpu/drm/drm_internal.h | 3 + > drivers/gpu/drm/drm_managed.c | 173 > include/drm/drm_device.h| 12 ++ > include/drm/drm_managed.h | 25 > include/drm/drm_print.h | 6 + > 8 files changed, 239 insertions(+), 2 deletions(-) > create mode 100644 drivers/gpu/drm/drm_managed.c > create mode 100644 include/drm/drm_managed.h > > diff --git a/Documentation/gpu/drm-internals.rst > b/Documentation/gpu/drm-internals.rst > index a73320576ca9..a6b6145fda78 100644 > --- a/Documentation/gpu/drm-internals.rst > +++ b/Documentation/gpu/drm-internals.rst > @@ -132,6 +132,12 @@ be unmapped; on many devices, the ROM address decoder is > shared with > other BARs, so leaving it mapped could cause undesired behaviour like > hangs or memory corruption. > > +Managed Resources > +- > + > +.. kernel-doc:: drivers/gpu/drm/drm_managed.c > + :doc: managed resources > + > Bus-specific Device Registration and PCI Support > > > diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile > index ca0ca775d37f..53d8fa170143 100644 > --- a/drivers/gpu/drm/Makefile > +++ b/drivers/gpu/drm/Makefile > @@ -17,7 +17,8 @@ drm-y := drm_auth.o drm_cache.o \ > drm_plane.o drm_color_mgmt.o drm_print.o \ > drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \ > drm_syncobj.o drm_lease.o drm_writeback.o drm_client.o \ > - drm_client_modeset.o drm_atomic_uapi.o drm_hdcp.o > + drm_client_modeset.o drm_atomic_uapi.o drm_hdcp.o \ > + drm_managed.o > > drm-$(CONFIG_DRM_LEGACY) += drm_legacy_misc.o drm_bufs.o drm_context.o > drm_dma.o drm_scatter.o drm_lock.o > drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o > diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c > index 9fcd6ab3c154..3e5627d6eba6 100644 > --- a/drivers/gpu/drm/drm_drv.c > +++ b/drivers/gpu/drm/drm_drv.c > @@ -629,6 +629,9 @@ int drm_dev_init(struct drm_device *dev, > dev->dev = get_device(parent); > dev->driver = driver; > > + INIT_LIST_HEAD(>managed.resources); > + spin_lock_init(>managed.lock); > + > /* no per-device feature limits by default */ > dev->driver_features = ~0u; > > @@ -828,8 +831,16 @@ static void drm_dev_release(struct kref *ref) > dev->driver->release(dev); > } else { > drm_dev_fini(dev); > - kfree(dev); > + if (!dev->managed.final_kfree) { > + WARN_ON(!list_empty(>managed.resources)); > + kfree(dev); > + } > } > + > + drm_managed_release(dev); > + > + if (dev->managed.final_kfree) > + kfree(dev->managed.final_kfree); > } > > /** > diff --git
[Intel-gfx] [PATCH 03/52] drm: add managed resources tied to drm_device
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 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. Cc: Greg Kroah-Hartman Cc: "Rafael J. Wysocki" Signed-off-by: Daniel Vetter --- Documentation/gpu/drm-internals.rst | 6 + drivers/gpu/drm/Makefile| 3 +- drivers/gpu/drm/drm_drv.c | 13 ++- drivers/gpu/drm/drm_internal.h | 3 + drivers/gpu/drm/drm_managed.c | 173 include/drm/drm_device.h| 12 ++ include/drm/drm_managed.h | 25 include/drm/drm_print.h | 6 + 8 files changed, 239 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/drm_managed.c create mode 100644 include/drm/drm_managed.h diff --git a/Documentation/gpu/drm-internals.rst b/Documentation/gpu/drm-internals.rst index a73320576ca9..a6b6145fda78 100644 --- a/Documentation/gpu/drm-internals.rst +++ b/Documentation/gpu/drm-internals.rst @@ -132,6 +132,12 @@ be unmapped; on many devices, the ROM address decoder is shared with other BARs, so leaving it mapped could cause undesired behaviour like hangs or memory corruption. +Managed Resources +- + +.. kernel-doc:: drivers/gpu/drm/drm_managed.c + :doc: managed resources + Bus-specific Device Registration and PCI Support diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index ca0ca775d37f..53d8fa170143 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -17,7 +17,8 @@ drm-y :=drm_auth.o drm_cache.o \ drm_plane.o drm_color_mgmt.o drm_print.o \ drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \ drm_syncobj.o drm_lease.o drm_writeback.o drm_client.o \ - drm_client_modeset.o drm_atomic_uapi.o drm_hdcp.o + drm_client_modeset.o drm_atomic_uapi.o drm_hdcp.o \ + drm_managed.o drm-$(CONFIG_DRM_LEGACY) += drm_legacy_misc.o drm_bufs.o drm_context.o drm_dma.o drm_scatter.o drm_lock.o drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 9fcd6ab3c154..3e5627d6eba6 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -629,6 +629,9 @@ int drm_dev_init(struct drm_device *dev, dev->dev = get_device(parent); dev->driver = driver; + INIT_LIST_HEAD(>managed.resources); + spin_lock_init(>managed.lock); + /* no per-device feature limits by default */ dev->driver_features = ~0u; @@ -828,8 +831,16 @@ static void drm_dev_release(struct kref *ref) dev->driver->release(dev); } else { drm_dev_fini(dev); - kfree(dev); + if (!dev->managed.final_kfree) { + WARN_ON(!list_empty(>managed.resources)); + kfree(dev); + } } + + drm_managed_release(dev); + + if (dev->managed.final_kfree) + kfree(dev->managed.final_kfree); } /** diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h index aeec2e68d772..8c2628dfc6c7 100644 --- a/drivers/gpu/drm/drm_internal.h +++ b/drivers/gpu/drm/drm_internal.h @@ -89,6 +89,9 @@ void