This section lists some common dilemmas and the standard solutions used in the Linux kernel code. If you use these, people will find your code simpler to understand.
If I could give you one piece of advice: never sleep with anyone crazier than yourself. But if I had to give you advice on locking: keep it simple.
Lock data, not code.
Be reluctant to introduce new locks.
Strangely enough, this is the exact reverse of my advice when you have slept with someone crazier than yourself.
There is a fairly common case where an interrupt handler needs access to a critical region, but does not need write access. In this case, you do not need to use read_lock_irq(), but only read_lock() everywhere (since if an interrupt occurs, the irq handler will only try to grab a read lock, which won't deadlock). You will still need to use write_lock_irq().
Similar logic applies to locking between softirqs/tasklets/BHs which never need a write lock, and user context: read_lock() and write_lock_bh().