locking/lockdep: Mark local_lock_t
The local_lock_t's are special, because they cannot form IRQ inversions, make sure we can tell them apart from the rest of the locks. Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
This commit is contained in:
parent
5831c0f71d
commit
dfd5e3f5fe
4 changed files with 39 additions and 15 deletions
|
@ -18,6 +18,7 @@ typedef struct {
|
||||||
.dep_map = { \
|
.dep_map = { \
|
||||||
.name = #lockname, \
|
.name = #lockname, \
|
||||||
.wait_type_inner = LD_WAIT_CONFIG, \
|
.wait_type_inner = LD_WAIT_CONFIG, \
|
||||||
|
.lock_type = LD_LOCK_PERCPU, \
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
# define LL_DEP_MAP_INIT(lockname)
|
# define LL_DEP_MAP_INIT(lockname)
|
||||||
|
@ -30,7 +31,9 @@ do { \
|
||||||
static struct lock_class_key __key; \
|
static struct lock_class_key __key; \
|
||||||
\
|
\
|
||||||
debug_check_no_locks_freed((void *)lock, sizeof(*lock));\
|
debug_check_no_locks_freed((void *)lock, sizeof(*lock));\
|
||||||
lockdep_init_map_wait(&(lock)->dep_map, #lock, &__key, 0, LD_WAIT_CONFIG);\
|
lockdep_init_map_type(&(lock)->dep_map, #lock, &__key, 0, \
|
||||||
|
LD_WAIT_CONFIG, LD_WAIT_INV, \
|
||||||
|
LD_LOCK_PERCPU); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
||||||
|
|
|
@ -185,12 +185,19 @@ extern void lockdep_unregister_key(struct lock_class_key *key);
|
||||||
* to lockdep:
|
* to lockdep:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern void lockdep_init_map_waits(struct lockdep_map *lock, const char *name,
|
extern void lockdep_init_map_type(struct lockdep_map *lock, const char *name,
|
||||||
struct lock_class_key *key, int subclass, short inner, short outer);
|
struct lock_class_key *key, int subclass, u8 inner, u8 outer, u8 lock_type);
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
lockdep_init_map_waits(struct lockdep_map *lock, const char *name,
|
||||||
|
struct lock_class_key *key, int subclass, u8 inner, u8 outer)
|
||||||
|
{
|
||||||
|
lockdep_init_map_type(lock, name, key, subclass, inner, LD_WAIT_INV, LD_LOCK_NORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
lockdep_init_map_wait(struct lockdep_map *lock, const char *name,
|
lockdep_init_map_wait(struct lockdep_map *lock, const char *name,
|
||||||
struct lock_class_key *key, int subclass, short inner)
|
struct lock_class_key *key, int subclass, u8 inner)
|
||||||
{
|
{
|
||||||
lockdep_init_map_waits(lock, name, key, subclass, inner, LD_WAIT_INV);
|
lockdep_init_map_waits(lock, name, key, subclass, inner, LD_WAIT_INV);
|
||||||
}
|
}
|
||||||
|
@ -340,6 +347,8 @@ static inline void lockdep_set_selftest_task(struct task_struct *task)
|
||||||
# define lock_set_class(l, n, k, s, i) do { } while (0)
|
# define lock_set_class(l, n, k, s, i) do { } while (0)
|
||||||
# define lock_set_subclass(l, s, i) do { } while (0)
|
# define lock_set_subclass(l, s, i) do { } while (0)
|
||||||
# define lockdep_init() do { } while (0)
|
# define lockdep_init() do { } while (0)
|
||||||
|
# define lockdep_init_map_type(lock, name, key, sub, inner, outer, type) \
|
||||||
|
do { (void)(name); (void)(key); } while (0)
|
||||||
# define lockdep_init_map_waits(lock, name, key, sub, inner, outer) \
|
# define lockdep_init_map_waits(lock, name, key, sub, inner, outer) \
|
||||||
do { (void)(name); (void)(key); } while (0)
|
do { (void)(name); (void)(key); } while (0)
|
||||||
# define lockdep_init_map_wait(lock, name, key, sub, inner) \
|
# define lockdep_init_map_wait(lock, name, key, sub, inner) \
|
||||||
|
|
|
@ -30,6 +30,12 @@ enum lockdep_wait_type {
|
||||||
LD_WAIT_MAX, /* must be last */
|
LD_WAIT_MAX, /* must be last */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum lockdep_lock_type {
|
||||||
|
LD_LOCK_NORMAL = 0, /* normal, catch all */
|
||||||
|
LD_LOCK_PERCPU, /* percpu */
|
||||||
|
LD_LOCK_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_LOCKDEP
|
#ifdef CONFIG_LOCKDEP
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -119,8 +125,10 @@ struct lock_class {
|
||||||
int name_version;
|
int name_version;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
short wait_type_inner;
|
u8 wait_type_inner;
|
||||||
short wait_type_outer;
|
u8 wait_type_outer;
|
||||||
|
u8 lock_type;
|
||||||
|
/* u8 hole; */
|
||||||
|
|
||||||
#ifdef CONFIG_LOCK_STAT
|
#ifdef CONFIG_LOCK_STAT
|
||||||
unsigned long contention_point[LOCKSTAT_POINTS];
|
unsigned long contention_point[LOCKSTAT_POINTS];
|
||||||
|
@ -169,8 +177,10 @@ struct lockdep_map {
|
||||||
struct lock_class_key *key;
|
struct lock_class_key *key;
|
||||||
struct lock_class *class_cache[NR_LOCKDEP_CACHING_CLASSES];
|
struct lock_class *class_cache[NR_LOCKDEP_CACHING_CLASSES];
|
||||||
const char *name;
|
const char *name;
|
||||||
short wait_type_outer; /* can be taken in this context */
|
u8 wait_type_outer; /* can be taken in this context */
|
||||||
short wait_type_inner; /* presents this context */
|
u8 wait_type_inner; /* presents this context */
|
||||||
|
u8 lock_type;
|
||||||
|
/* u8 hole; */
|
||||||
#ifdef CONFIG_LOCK_STAT
|
#ifdef CONFIG_LOCK_STAT
|
||||||
int cpu;
|
int cpu;
|
||||||
unsigned long ip;
|
unsigned long ip;
|
||||||
|
|
|
@ -1290,6 +1290,7 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force)
|
||||||
class->name_version = count_matching_names(class);
|
class->name_version = count_matching_names(class);
|
||||||
class->wait_type_inner = lock->wait_type_inner;
|
class->wait_type_inner = lock->wait_type_inner;
|
||||||
class->wait_type_outer = lock->wait_type_outer;
|
class->wait_type_outer = lock->wait_type_outer;
|
||||||
|
class->lock_type = lock->lock_type;
|
||||||
/*
|
/*
|
||||||
* We use RCU's safe list-add method to make
|
* We use RCU's safe list-add method to make
|
||||||
* parallel walking of the hash-list safe:
|
* parallel walking of the hash-list safe:
|
||||||
|
@ -4503,9 +4504,9 @@ print_lock_invalid_wait_context(struct task_struct *curr,
|
||||||
*/
|
*/
|
||||||
static int check_wait_context(struct task_struct *curr, struct held_lock *next)
|
static int check_wait_context(struct task_struct *curr, struct held_lock *next)
|
||||||
{
|
{
|
||||||
short next_inner = hlock_class(next)->wait_type_inner;
|
u8 next_inner = hlock_class(next)->wait_type_inner;
|
||||||
short next_outer = hlock_class(next)->wait_type_outer;
|
u8 next_outer = hlock_class(next)->wait_type_outer;
|
||||||
short curr_inner;
|
u8 curr_inner;
|
||||||
int depth;
|
int depth;
|
||||||
|
|
||||||
if (!curr->lockdep_depth || !next_inner || next->trylock)
|
if (!curr->lockdep_depth || !next_inner || next->trylock)
|
||||||
|
@ -4528,7 +4529,7 @@ static int check_wait_context(struct task_struct *curr, struct held_lock *next)
|
||||||
|
|
||||||
for (; depth < curr->lockdep_depth; depth++) {
|
for (; depth < curr->lockdep_depth; depth++) {
|
||||||
struct held_lock *prev = curr->held_locks + depth;
|
struct held_lock *prev = curr->held_locks + depth;
|
||||||
short prev_inner = hlock_class(prev)->wait_type_inner;
|
u8 prev_inner = hlock_class(prev)->wait_type_inner;
|
||||||
|
|
||||||
if (prev_inner) {
|
if (prev_inner) {
|
||||||
/*
|
/*
|
||||||
|
@ -4577,9 +4578,9 @@ static inline int check_wait_context(struct task_struct *curr,
|
||||||
/*
|
/*
|
||||||
* Initialize a lock instance's lock-class mapping info:
|
* Initialize a lock instance's lock-class mapping info:
|
||||||
*/
|
*/
|
||||||
void lockdep_init_map_waits(struct lockdep_map *lock, const char *name,
|
void lockdep_init_map_type(struct lockdep_map *lock, const char *name,
|
||||||
struct lock_class_key *key, int subclass,
|
struct lock_class_key *key, int subclass,
|
||||||
short inner, short outer)
|
u8 inner, u8 outer, u8 lock_type)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -4602,6 +4603,7 @@ void lockdep_init_map_waits(struct lockdep_map *lock, const char *name,
|
||||||
|
|
||||||
lock->wait_type_outer = outer;
|
lock->wait_type_outer = outer;
|
||||||
lock->wait_type_inner = inner;
|
lock->wait_type_inner = inner;
|
||||||
|
lock->lock_type = lock_type;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* No key, no joy, we need to hash something.
|
* No key, no joy, we need to hash something.
|
||||||
|
@ -4636,7 +4638,7 @@ void lockdep_init_map_waits(struct lockdep_map *lock, const char *name,
|
||||||
raw_local_irq_restore(flags);
|
raw_local_irq_restore(flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(lockdep_init_map_waits);
|
EXPORT_SYMBOL_GPL(lockdep_init_map_type);
|
||||||
|
|
||||||
struct lock_class_key __lockdep_no_validate__;
|
struct lock_class_key __lockdep_no_validate__;
|
||||||
EXPORT_SYMBOL_GPL(__lockdep_no_validate__);
|
EXPORT_SYMBOL_GPL(__lockdep_no_validate__);
|
||||||
|
|
Loading…
Add table
Reference in a new issue