>> > However, the interface iterator will simply not run at all if ->stop has >> > already succeeded since no interfaces would be UP, so you don't really >> > have to protect it against that, you only have to make sure it's not >> > running when you unregister your hardware struct, and _that_ doesn't >> > have the rtnl taken so you can use cancel_work_sync() there. >> >> True, but the race condition happens when ieee80211_stop() is called, >> and the rt2x00 work is triggered before before >> rt2x00->remove_interface() or rt2x00>stop() is called. when stop() is >> then called it cannot use cancel_work_sync() because >> the work structure is waiting until stop() has completed which will >> not end until cancel_work_sync() has completed. > > No, but I'm saying that ->stop doesn't need to cancel_work_sync(). You > should have a work struct that you exclusively use for whatever you need > to do with interfaces, so the code looks something like this: > > void work(...) > { > iterate_interfaces(); > } > > maybe with some additional locking. You also use schedule_work() and not > the mac80211-provided workqueue. > > This work will do exactly nothing if triggered before ->stop and running > after ->stop because all interfaces will be gone. Hence, you don't need > to cancel it in ->stop, you don't care whether it'll run or not. > > Hence, the only thing you need to take care of is that it's canceled > before unregister_hw(), and for that you can use cancel_work_sync(). Ah yes, I understand what you mean now. That would indeed work, I'll get a patch ready that does exactly that. > Am I missing something? Nope, I was missing something. ;) Thanks. Ivo -- 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