Search Linux Wireless

Re: [PATCH] iwlwifi: remove input device and fix rfkill state

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, 03 Jul 2008, Ivo van Doorn wrote:
> On Wednesday 02 July 2008, Henrique de Moraes Holschuh wrote:
> > On Wed, 02 Jul 2008, Ivo van Doorn wrote:
> > > Well actually it isn't that easy, the lock would also be used for the state change
> > > callback function toward the driver. And if that is done under a spinlock, USB
> > > drivers will start complaining since they can't access the hardware under atomic
> > > context...
> > 
> > Would it be worth it to use a hybrid scheme?
> 
> That would be nice if it could be done cleanly.

If it can't be done cleanly, it is best not done at all IMHO...

> > Callbacks and the notify chain would remain in task context, while the
> > locking is changed to spinlocks so that it can also work in interrupt
> > context when needed.   We document better (in the text documentation,
> > include files and kernel-doc) the contextes so that people don't get
> > confused by the code and think that a spinlock means atomic context is OK
> > for these handlers.
> 
> The mutex in the rfkill structure could become a spinlock, but the notifiers
> should probably be switched to the atomic versions as well so they could still
> be used at the current locations.

The kind of stuff we do in the notifiers usually benefits from task context,
I'd rather add a rfkill workqueue and call the notifiers from there when
needed (i.e. when we call from inside rfkill_force_state_atomic).

Other than calling LED triggers, everything else one typically would use the
notifier chain for (sending uevents, sending input evets) is best done from
task context, anyway.

> The global rfkill_mutex could remain a mutex to protect the rfkill list and all
> callback functions.

Yes, we could do that for the rfkill list, but shouldn't all callbacks and
all fields inside a rfkill struct be protected by the rfkill->mutex instead
of by the global mutex?

If a driver wants any more locking so as not to get two of its rfkill
callbacks (when it handles more than one rfkill device) called concurrently,
it is its business to do it.

> Now that I rechecked the code the current approach doesn't seem to protect the
> rfkill_toggle_radio callback function with consistent locking either.
> Sometimes it is called under the rfkill->mutex protection and at other times
> under the global rfkill_mutex.
> Both rfkill_state_store() and rfkill_resume() use the rfkill->mutex while most
> other functions use the global rfkill_mutex. Those 2 will have to switch over to
> the global mutex to prevent problems.

Actually, see above... Shouldn't we protect everything inside a rfkill
struct with rfkill->mutex, and outside stuff with the global mutex?

And I fear we could do better in the rfkill struct refcouting area, too.
The code I submitted does no refcounting, and it exposes the rfkill struct a
lot.  Even under the protection of the mutexes, it was probably unwise for
me to do it that way without some refcounting paranoia.  Especially when
schedule_work is involved...

> > For rfkill_force_state(), we'd either add a flags parameter that can take,
> > e.g., GFP_ATOMIC, to tell us whether it is being called from an interrupt
> > handler or a task context, or we could simply add rfkill_force_state_atomic().
> 
> Neither sound like a good idea, because that would require 2 approaches to lock
> the rfkill structure which could be good cause for race conditions under certain
> situations.

[...]

> > This would be safer (because the state would still be updated synchronously
> > when one calls rfkill_force_state(_atomic)?) than adding a
> > rfkill_schedule_force_state() for drivers to call in interrupt context.
> 
> Couldn't this cause race conditions in toggle_radio updates when 1 driver uses atomic
> context and the other in scheduled context.

Hmm, it could cause deadlocks I think.  task context takes lock.  interrupt
context tries to run, needs lock, keeps spinning forever waiting for it, and
if we are not SMP, task context never has a chance to release the lock, so
we get a deadlock.  Is this correct?

If it is, we better make the atomic path lock-free.  Argh.  This means
rfkill->state (the only thing we care about in the atomic path) would have
to become an atomic variable, and the code changed to cope with its value
being "volatile", so that it can be used in a lockless fashion.

It is doable, I think, although it is quite annoying.

-- 
  "One disk to rule them all, One disk to find them. One disk to bring
  them all and in the darkness grind them. In the Land of Redmond
  where the shadows lie." -- The Silicon Valley Tarot
  Henrique Holschuh
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux