You have already learned that the one thing we should not do is sleep (block) in any kind of atomic or interrupt context. Let's put this to the test. As always, the empirical approach – where you test things for yourself rather than relying on other's experiences – is key!
How exactly can we test this? Easy: we shall use a simple integer module parameter, buggy, that, when set to 1 (the default value being 0), executes a code path within our spinlock's critical section that violates this rule. We shall invoke the schedule_timeout() API (which, as you learned in Chapter 15, Timers, Kernel Threads, and More, in the Understanding how to use the *sleep() blocking APIs section) internally invokes schedule(); it's how we go to sleep in the kernel space). Here's the relevant code:
// ch12/2_miscdrv_rdwr_spinlock/2_miscdrv_rdwr_spinlock.c
[ ... ]
static int buggy;
module_param(buggy...