<div dir="ltr">Hi Daniel,<br><br>This is the previous patch relevant to this discussion:<br><a href="https://patchwork.freedesktop.org/patch/314343/">https://patchwork.freedesktop.org/patch/314343/</a><br><br>So before I refactored the code to leverage drm_minor, I kept my own list of "known" drm_device inside the controller and have explicit register and unregister function to init per device cgroup defaults.  For v4, I refactored the per device cgroup properties and embedded them into the drm_device and continue to only use the primary minor as a way to index the device as v3.<div><br></div><div>Regards,<br>Kenny</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Sep 4, 2019 at 4:54 AM Daniel Vetter <<a href="mailto:daniel@ffwll.ch">daniel@ffwll.ch</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Tue, Sep 03, 2019 at 04:43:45PM -0400, Kenny Ho wrote:<br>
> On Tue, Sep 3, 2019 at 4:12 PM Daniel Vetter <<a href="mailto:daniel@ffwll.ch" target="_blank">daniel@ffwll.ch</a>> wrote:<br>
> > On Tue, Sep 3, 2019 at 9:45 PM Kenny Ho <<a href="mailto:y2kenny@gmail.com" target="_blank">y2kenny@gmail.com</a>> wrote:<br>
> > > On Tue, Sep 3, 2019 at 3:57 AM Daniel Vetter <<a href="mailto:daniel@ffwll.ch" target="_blank">daniel@ffwll.ch</a>> wrote:<br>
> > > > Iterating over minors for cgroups sounds very, very wrong. Why do we care<br>
> > > > whether a buffer was allocated through kms dumb vs render nodes?<br>
> > > ><br>
> > > > I'd expect all the cgroup stuff to only work on drm_device, if it does<br>
> > > > care about devices.<br>
> > > ><br>
> > > > (I didn't look through the patch series to find out where exactly you're<br>
> > > > using this, so maybe I'm off the rails here).<br>
> > ><br>
> > > I am exposing this to remove the need to keep track of a separate list<br>
> > > of available drm_device in the system (to remove the registering and<br>
> > > unregistering of drm_device to the cgroup subsystem and just use<br>
> > > drm_minor as the single source of truth.)  I am only filtering out the<br>
> > > render nodes minor because they point to the same drm_device and is<br>
> > > confusing.<br>
> > ><br>
> > > Perhaps I missed an obvious way to list the drm devices without<br>
> > > iterating through the drm_minors?  (I probably jumped to the minors<br>
> > > because $major:$minor is the convention to address devices in cgroup.)<br>
> ><br>
> > Create your own if there's nothing, because you need to anyway:<br>
> > - You need special locking anyway, we can't just block on the idr lock<br>
> > for everything.<br>
> > - This needs to refcount drm_device, no the minors.<br>
> ><br>
> > Iterating over stuff still feels kinda wrong still, because normally<br>
> > the way we register/unregister userspace api (and cgroups isn't<br>
> > anything else from a drm driver pov) is by adding more calls to<br>
> > drm_dev_register/unregister. If you put a drm_cg_register/unregister<br>
> > call in there we have a clean separation, and you can track all the<br>
> > currently active devices however you want. Iterating over objects that<br>
> > can be hotunplugged any time tends to get really complicated really<br>
> > quickly.<br>
> <br>
> Um... I thought this is what I had previously.  Did I misunderstood<br>
> your feedback from v3?  Doesn't drm_minor already include all these<br>
> facilities so isn't creating my own kind of reinventing the wheel?<br>
> (as I did previously?)  drm_minor_register is called inside<br>
> drm_dev_register so isn't leveraging existing drm_minor facilities<br>
> much better solution?<br>
<br>
Hm the previous version already dropped out of my inbox, so hard to find<br>
it again. And I couldn't find this in archieves. Do you have pointers?<br>
<br>
I thought the previous version did cgroup init separately from drm_device<br>
setup, and I guess I suggested that it should be moved int<br>
drm_dev_register/unregister?<br>
<br>
Anyway, I don't think reusing the drm_minor registration makes sense,<br>
since we want to be on the drm_device, not on the minor. Which is a bit<br>
awkward for cgroups, which wants to identify devices using major.minor<br>
pairs. But I guess drm is the first subsystem where 1 device can be<br>
exposed through multiple minors ...<br>
<br>
Tejun, any suggestions on this?<br>
<br>
Anyway, I think just leveraging existing code because it can be abused to<br>
make it fit for us doesn't make sense. E.g. for the kms side we also don't<br>
piggy-back on top of drm_minor_register (it would be technically<br>
possible), but instead we have drm_modeset_register_all().<br>
-Daniel<br>
<br>
> <br>
> Kenny<br>
> <br>
> ><br>
> ><br>
> > ><br>
> > > Kenny<br>
> > ><br>
> > > > -Daniel<br>
> > > ><br>
> > > > > ---<br>
> > > > >  drivers/gpu/drm/drm_drv.c      | 19 +++++++++++++++++++<br>
> > > > >  drivers/gpu/drm/drm_internal.h |  4 ----<br>
> > > > >  include/drm/drm_drv.h          |  4 ++++<br>
> > > > >  3 files changed, 23 insertions(+), 4 deletions(-)<br>
> > > > ><br>
> > > > > diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c<br>
> > > > > index 862621494a93..000cddabd970 100644<br>
> > > > > --- a/drivers/gpu/drm/drm_drv.c<br>
> > > > > +++ b/drivers/gpu/drm/drm_drv.c<br>
> > > > > @@ -254,11 +254,13 @@ struct drm_minor *drm_minor_acquire(unsigned int minor_id)<br>
> > > > ><br>
> > > > >       return minor;<br>
> > > > >  }<br>
> > > > > +EXPORT_SYMBOL(drm_minor_acquire);<br>
> > > > ><br>
> > > > >  void drm_minor_release(struct drm_minor *minor)<br>
> > > > >  {<br>
> > > > >       drm_dev_put(minor->dev);<br>
> > > > >  }<br>
> > > > > +EXPORT_SYMBOL(drm_minor_release);<br>
> > > > ><br>
> > > > >  /**<br>
> > > > >   * DOC: driver instance overview<br>
> > > > > @@ -1078,6 +1080,23 @@ int drm_dev_set_unique(struct drm_device *dev, const char *name)<br>
> > > > >  }<br>
> > > > >  EXPORT_SYMBOL(drm_dev_set_unique);<br>
> > > > ><br>
> > > > > +/**<br>
> > > > > + * drm_minor_for_each - Iterate through all stored DRM minors<br>
> > > > > + * @fn: Function to be called for each pointer.<br>
> > > > > + * @data: Data passed to callback function.<br>
> > > > > + *<br>
> > > > > + * The callback function will be called for each @drm_minor entry, passing<br>
> > > > > + * the minor, the entry and @data.<br>
> > > > > + *<br>
> > > > > + * If @fn returns anything other than %0, the iteration stops and that<br>
> > > > > + * value is returned from this function.<br>
> > > > > + */<br>
> > > > > +int drm_minor_for_each(int (*fn)(int id, void *p, void *data), void *data)<br>
> > > > > +{<br>
> > > > > +     return idr_for_each(&drm_minors_idr, fn, data);<br>
> > > > > +}<br>
> > > > > +EXPORT_SYMBOL(drm_minor_for_each);<br>
> > > > > +<br>
> > > > >  /*<br>
> > > > >   * DRM Core<br>
> > > > >   * The DRM core module initializes all global DRM objects and makes them<br>
> > > > > diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h<br>
> > > > > index e19ac7ca602d..6bfad76f8e78 100644<br>
> > > > > --- a/drivers/gpu/drm/drm_internal.h<br>
> > > > > +++ b/drivers/gpu/drm/drm_internal.h<br>
> > > > > @@ -54,10 +54,6 @@ void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv);<br>
> > > > >  void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private *prime_fpriv,<br>
> > > > >                                       struct dma_buf *dma_buf);<br>
> > > > ><br>
> > > > > -/* drm_drv.c */<br>
> > > > > -struct drm_minor *drm_minor_acquire(unsigned int minor_id);<br>
> > > > > -void drm_minor_release(struct drm_minor *minor);<br>
> > > > > -<br>
> > > > >  /* drm_vblank.c */<br>
> > > > >  void drm_vblank_disable_and_save(struct drm_device *dev, unsigned int pipe);<br>
> > > > >  void drm_vblank_cleanup(struct drm_device *dev);<br>
> > > > > diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h<br>
> > > > > index 68ca736c548d..24f8d054c570 100644<br>
> > > > > --- a/include/drm/drm_drv.h<br>
> > > > > +++ b/include/drm/drm_drv.h<br>
> > > > > @@ -799,5 +799,9 @@ static inline bool drm_drv_uses_atomic_modeset(struct drm_device *dev)<br>
> > > > ><br>
> > > > >  int drm_dev_set_unique(struct drm_device *dev, const char *name);<br>
> > > > ><br>
> > > > > +int drm_minor_for_each(int (*fn)(int id, void *p, void *data), void *data);<br>
> > > > > +<br>
> > > > > +struct drm_minor *drm_minor_acquire(unsigned int minor_id);<br>
> > > > > +void drm_minor_release(struct drm_minor *minor);<br>
> > > > ><br>
> > > > >  #endif<br>
> > > > > --<br>
> > > > > 2.22.0<br>
> > > > ><br>
> > > ><br>
> > > > --<br>
> > > > Daniel Vetter<br>
> > > > Software Engineer, Intel Corporation<br>
> > > > <a href="http://blog.ffwll.ch" rel="noreferrer" target="_blank">http://blog.ffwll.ch</a><br>
> ><br>
> ><br>
> ><br>
> > --<br>
> > Daniel Vetter<br>
> > Software Engineer, Intel Corporation<br>
> > +41 (0) 79 365 57 48 - <a href="http://blog.ffwll.ch" rel="noreferrer" target="_blank">http://blog.ffwll.ch</a><br>
<br>
-- <br>
Daniel Vetter<br>
Software Engineer, Intel Corporation<br>
<a href="http://blog.ffwll.ch" rel="noreferrer" target="_blank">http://blog.ffwll.ch</a><br>
</blockquote></div>