[linux-dvb] idea on how to break the static dependencies on
Andrew de Quincey
adq_dvb at lidskialf.net
Mon May 8 01:11:09 CEST 2006
On Friday 05 May 2006 01:55, Trent Piepho wrote:
> On Thu, 4 May 2006, Andrew de Quincey wrote:
> > There is one issue with using any of the methods in dvb_frontend_ops -
> > the API is designed so that multiple devices can hook into the ops
> > structure and override functions or even chain them - those methods
> > aren't necessarily pointing at the demod module. It could be pointing at
> > something else. In fact the lnbp21_attach() method does exactly this.
> That does throw a monkey wrench in my plan.
> How about this:
> The dvb_frontend struct gets a new field, 'module'. The FE attach function
> sets it to THIS_MODULE, ie. it points to the FE module. After the card
> driver calls the FE's release() method, it does a put on the module field
> (it saves it before it calls release of course). If the FE attach function
> is called without using dvb_attach() it doesn't matter, the module field is
> set and then just ignored.
> This doesn't use symbol_put_addr() and doesn't use fe_ops either. Still
> doesn't have any nice chaining ability.
> This means all the FEs have to add the module field and code to set it.
> The first method didn't require the FEs to do anything, and if the kernel
> was compiled without modules the whole attach/get/put business would just
> automagically disappear.
Yeah that would work for the single-module situation but as you say, it breaks
the chaining.. hmm, maybe if we think along these lines we can come up with
> > This is kinda why I am so keen on having the release() methods themselves
> > do the counting; it would automatically tidy up these chained devices.
> Is there a race condition if that is done? If the card driver puts the
> module after release, the module stays "locked" until nothing is using it
> in any way. If the release() method puts itself, then the module is
> "unlocked" while one of its methods is still executing. Maybe that's not a
> problem and the kernel module unload code takes care of it?
Hmm, that throws a monkey wrench into my plan as well :)
OK... the release() method is only called from
dvb_frontend.c/dvb_unregister_frontend(). What about something like this:
each XXX_attach() method does the current behaviour - replace the current
release() pointer and preserve the old pointer.
When you call dvb_unregister_frontend(), it calls the the release() pointer as
it does just now. This causes _only_ the last attached object to do whatever
it has to. It then updates the release() pointer field with the previous
release() pointer, and returns a THIS_MODULE pointer (or NULL).
dvb_unregister_frontend can then decrement the module counter without having
the possible race condition.
Enclose that in a while loop, and you also support chaining... e.g.:
struct module *m = fe->ops->release(fe);
if (m) module_put(m);
(the above is just a quick example; its probably got lots of errors :)
More information about the linux-dvb