[linux-dvb] idea on how to break the static dependencies on demodulator modules

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.:

while(fe->ops->release) {
	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 mailing list