Commit 8f45c1a5 authored by Linus Torvalds's avatar Linus Torvalds

block: fix queue locking verification

The new queue_flag_set/clear() functions verify that the queue is
locked, but in doing so they will actually instead oops if the queue
lock hasn't been initialized at all.

So fix the lock debug test to consider the "no lock" case to be
unlocked.  This way you get a nice WARN_ON_ONCE() instead of a fatal
oops.

Bug introduced by commit 75ad23bc
("block: make queue flags non-atomic").

Cc: Jens Axboe <jens.axboe@oracle.com>
Cc: Nick Piggin <npiggin@suse.de>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 25a02586
...@@ -410,6 +410,12 @@ struct request_queue ...@@ -410,6 +410,12 @@ struct request_queue
#define QUEUE_FLAG_BIDI 9 /* queue supports bidi requests */ #define QUEUE_FLAG_BIDI 9 /* queue supports bidi requests */
#define QUEUE_FLAG_NOMERGES 10 /* disable merge attempts */ #define QUEUE_FLAG_NOMERGES 10 /* disable merge attempts */
static inline int queue_is_locked(struct request_queue *q)
{
spinlock_t *lock = q->queue_lock;
return lock && spin_is_locked(lock);
}
static inline void queue_flag_set_unlocked(unsigned int flag, static inline void queue_flag_set_unlocked(unsigned int flag,
struct request_queue *q) struct request_queue *q)
{ {
...@@ -418,7 +424,7 @@ static inline void queue_flag_set_unlocked(unsigned int flag, ...@@ -418,7 +424,7 @@ static inline void queue_flag_set_unlocked(unsigned int flag,
static inline void queue_flag_set(unsigned int flag, struct request_queue *q) static inline void queue_flag_set(unsigned int flag, struct request_queue *q)
{ {
WARN_ON_ONCE(!spin_is_locked(q->queue_lock)); WARN_ON_ONCE(!queue_is_locked(q));
__set_bit(flag, &q->queue_flags); __set_bit(flag, &q->queue_flags);
} }
...@@ -430,7 +436,7 @@ static inline void queue_flag_clear_unlocked(unsigned int flag, ...@@ -430,7 +436,7 @@ static inline void queue_flag_clear_unlocked(unsigned int flag,
static inline void queue_flag_clear(unsigned int flag, struct request_queue *q) static inline void queue_flag_clear(unsigned int flag, struct request_queue *q)
{ {
WARN_ON_ONCE(!spin_is_locked(q->queue_lock)); WARN_ON_ONCE(!queue_is_locked(q));
__clear_bit(flag, &q->queue_flags); __clear_bit(flag, &q->queue_flags);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment