diff options
Diffstat (limited to 'kernel/lockdep.c')
-rw-r--r-- | kernel/lockdep.c | 528 |
1 files changed, 271 insertions, 257 deletions
diff --git a/kernel/lockdep.c b/kernel/lockdep.c index 06b0c3568f0b..3673a3f44d9d 100644 --- a/kernel/lockdep.c +++ b/kernel/lockdep.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/utsname.h> | 41 | #include <linux/utsname.h> |
42 | #include <linux/hash.h> | 42 | #include <linux/hash.h> |
43 | #include <linux/ftrace.h> | 43 | #include <linux/ftrace.h> |
44 | #include <linux/stringify.h> | ||
44 | 45 | ||
45 | #include <asm/sections.h> | 46 | #include <asm/sections.h> |
46 | 47 | ||
@@ -310,12 +311,14 @@ EXPORT_SYMBOL(lockdep_on); | |||
310 | #if VERBOSE | 311 | #if VERBOSE |
311 | # define HARDIRQ_VERBOSE 1 | 312 | # define HARDIRQ_VERBOSE 1 |
312 | # define SOFTIRQ_VERBOSE 1 | 313 | # define SOFTIRQ_VERBOSE 1 |
314 | # define RECLAIM_VERBOSE 1 | ||
313 | #else | 315 | #else |
314 | # define HARDIRQ_VERBOSE 0 | 316 | # define HARDIRQ_VERBOSE 0 |
315 | # define SOFTIRQ_VERBOSE 0 | 317 | # define SOFTIRQ_VERBOSE 0 |
318 | # define RECLAIM_VERBOSE 0 | ||
316 | #endif | 319 | #endif |
317 | 320 | ||
318 | #if VERBOSE || HARDIRQ_VERBOSE || SOFTIRQ_VERBOSE | 321 | #if VERBOSE || HARDIRQ_VERBOSE || SOFTIRQ_VERBOSE || RECLAIM_VERBOSE |
319 | /* | 322 | /* |
320 | * Quick filtering for interesting events: | 323 | * Quick filtering for interesting events: |
321 | */ | 324 | */ |
@@ -443,17 +446,18 @@ atomic_t nr_find_usage_backwards_recursions; | |||
443 | * Locking printouts: | 446 | * Locking printouts: |
444 | */ | 447 | */ |
445 | 448 | ||
449 | #define __USAGE(__STATE) \ | ||
450 | [LOCK_USED_IN_##__STATE] = "IN-"__stringify(__STATE)"-W", \ | ||
451 | [LOCK_ENABLED_##__STATE] = __stringify(__STATE)"-ON-W", \ | ||
452 | [LOCK_USED_IN_##__STATE##_READ] = "IN-"__stringify(__STATE)"-R",\ | ||
453 | [LOCK_ENABLED_##__STATE##_READ] = __stringify(__STATE)"-ON-R", | ||
454 | |||
446 | static const char *usage_str[] = | 455 | static const char *usage_str[] = |
447 | { | 456 | { |
448 | [LOCK_USED] = "initial-use ", | 457 | #define LOCKDEP_STATE(__STATE) __USAGE(__STATE) |
449 | [LOCK_USED_IN_HARDIRQ] = "in-hardirq-W", | 458 | #include "lockdep_states.h" |
450 | [LOCK_USED_IN_SOFTIRQ] = "in-softirq-W", | 459 | #undef LOCKDEP_STATE |
451 | [LOCK_ENABLED_SOFTIRQS] = "softirq-on-W", | 460 | [LOCK_USED] = "INITIAL USE", |
452 | [LOCK_ENABLED_HARDIRQS] = "hardirq-on-W", | ||
453 | [LOCK_USED_IN_HARDIRQ_READ] = "in-hardirq-R", | ||
454 | [LOCK_USED_IN_SOFTIRQ_READ] = "in-softirq-R", | ||
455 | [LOCK_ENABLED_SOFTIRQS_READ] = "softirq-on-R", | ||
456 | [LOCK_ENABLED_HARDIRQS_READ] = "hardirq-on-R", | ||
457 | }; | 461 | }; |
458 | 462 | ||
459 | const char * __get_key_name(struct lockdep_subclass_key *key, char *str) | 463 | const char * __get_key_name(struct lockdep_subclass_key *key, char *str) |
@@ -461,46 +465,45 @@ const char * __get_key_name(struct lockdep_subclass_key *key, char *str) | |||
461 | return kallsyms_lookup((unsigned long)key, NULL, NULL, NULL, str); | 465 | return kallsyms_lookup((unsigned long)key, NULL, NULL, NULL, str); |
462 | } | 466 | } |
463 | 467 | ||
464 | void | 468 | static inline unsigned long lock_flag(enum lock_usage_bit bit) |
465 | get_usage_chars(struct lock_class *class, char *c1, char *c2, char *c3, char *c4) | ||
466 | { | 469 | { |
467 | *c1 = '.', *c2 = '.', *c3 = '.', *c4 = '.'; | 470 | return 1UL << bit; |
468 | 471 | } | |
469 | if (class->usage_mask & LOCKF_USED_IN_HARDIRQ) | ||
470 | *c1 = '+'; | ||
471 | else | ||
472 | if (class->usage_mask & LOCKF_ENABLED_HARDIRQS) | ||
473 | *c1 = '-'; | ||
474 | 472 | ||
475 | if (class->usage_mask & LOCKF_USED_IN_SOFTIRQ) | 473 | static char get_usage_char(struct lock_class *class, enum lock_usage_bit bit) |
476 | *c2 = '+'; | 474 | { |
477 | else | 475 | char c = '.'; |
478 | if (class->usage_mask & LOCKF_ENABLED_SOFTIRQS) | ||
479 | *c2 = '-'; | ||
480 | 476 | ||
481 | if (class->usage_mask & LOCKF_ENABLED_HARDIRQS_READ) | 477 | if (class->usage_mask & lock_flag(bit + 2)) |
482 | *c3 = '-'; | 478 | c = '+'; |
483 | if (class->usage_mask & LOCKF_USED_IN_HARDIRQ_READ) { | 479 | if (class->usage_mask & lock_flag(bit)) { |
484 | *c3 = '+'; | 480 | c = '-'; |
485 | if (class->usage_mask & LOCKF_ENABLED_HARDIRQS_READ) | 481 | if (class->usage_mask & lock_flag(bit + 2)) |
486 | *c3 = '?'; | 482 | c = '?'; |
487 | } | 483 | } |
488 | 484 | ||
489 | if (class->usage_mask & LOCKF_ENABLED_SOFTIRQS_READ) | 485 | return c; |
490 | *c4 = '-'; | 486 | } |
491 | if (class->usage_mask & LOCKF_USED_IN_SOFTIRQ_READ) { | 487 | |
492 | *c4 = '+'; | 488 | void get_usage_chars(struct lock_class *class, char usage[LOCK_USAGE_CHARS]) |
493 | if (class->usage_mask & LOCKF_ENABLED_SOFTIRQS_READ) | 489 | { |
494 | *c4 = '?'; | 490 | int i = 0; |
495 | } | 491 | |
492 | #define LOCKDEP_STATE(__STATE) \ | ||
493 | usage[i++] = get_usage_char(class, LOCK_USED_IN_##__STATE); \ | ||
494 | usage[i++] = get_usage_char(class, LOCK_USED_IN_##__STATE##_READ); | ||
495 | #include "lockdep_states.h" | ||
496 | #undef LOCKDEP_STATE | ||
497 | |||
498 | usage[i] = '\0'; | ||
496 | } | 499 | } |
497 | 500 | ||
498 | static void print_lock_name(struct lock_class *class) | 501 | static void print_lock_name(struct lock_class *class) |
499 | { | 502 | { |
500 | char str[KSYM_NAME_LEN], c1, c2, c3, c4; | 503 | char str[KSYM_NAME_LEN], usage[LOCK_USAGE_CHARS]; |
501 | const char *name; | 504 | const char *name; |
502 | 505 | ||
503 | get_usage_chars(class, &c1, &c2, &c3, &c4); | 506 | get_usage_chars(class, usage); |
504 | 507 | ||
505 | name = class->name; | 508 | name = class->name; |
506 | if (!name) { | 509 | if (!name) { |
@@ -513,7 +516,7 @@ static void print_lock_name(struct lock_class *class) | |||
513 | if (class->subclass) | 516 | if (class->subclass) |
514 | printk("/%d", class->subclass); | 517 | printk("/%d", class->subclass); |
515 | } | 518 | } |
516 | printk("){%c%c%c%c}", c1, c2, c3, c4); | 519 | printk("){%s}", usage); |
517 | } | 520 | } |
518 | 521 | ||
519 | static void print_lockdep_cache(struct lockdep_map *lock) | 522 | static void print_lockdep_cache(struct lockdep_map *lock) |
@@ -1263,9 +1266,49 @@ check_usage(struct task_struct *curr, struct held_lock *prev, | |||
1263 | bit_backwards, bit_forwards, irqclass); | 1266 | bit_backwards, bit_forwards, irqclass); |
1264 | } | 1267 | } |
1265 | 1268 | ||
1266 | static int | 1269 | static const char *state_names[] = { |
1267 | check_prev_add_irq(struct task_struct *curr, struct held_lock *prev, | 1270 | #define LOCKDEP_STATE(__STATE) \ |
1268 | struct held_lock *next) | 1271 | __stringify(__STATE), |
1272 | #include "lockdep_states.h" | ||
1273 | #undef LOCKDEP_STATE | ||
1274 | }; | ||
1275 | |||
1276 | static const char *state_rnames[] = { | ||
1277 | #define LOCKDEP_STATE(__STATE) \ | ||
1278 | __stringify(__STATE)"-READ", | ||
1279 | #include "lockdep_states.h" | ||
1280 | #undef LOCKDEP_STATE | ||
1281 | }; | ||
1282 | |||
1283 | static inline const char *state_name(enum lock_usage_bit bit) | ||
1284 | { | ||
1285 | return (bit & 1) ? state_rnames[bit >> 2] : state_names[bit >> 2]; | ||
1286 | } | ||
1287 | |||
1288 | static int exclusive_bit(int new_bit) | ||
1289 | { | ||
1290 | /* | ||
1291 | * USED_IN | ||
1292 | * USED_IN_READ | ||
1293 | * ENABLED | ||
1294 | * ENABLED_READ | ||
1295 | * | ||
1296 | * bit 0 - write/read | ||
1297 | * bit 1 - used_in/enabled | ||
1298 | * bit 2+ state | ||
1299 | */ | ||
1300 | |||
1301 | int state = new_bit & ~3; | ||
1302 | int dir = new_bit & 2; | ||
1303 | |||
1304 | /* | ||
1305 | * keep state, bit flip the direction and strip read. | ||
1306 | */ | ||
1307 | return state | (dir ^ 2); | ||
1308 | } | ||
1309 | |||
1310 | static int check_irq_usage(struct task_struct *curr, struct held_lock *prev, | ||
1311 | struct held_lock *next, enum lock_usage_bit bit) | ||
1269 | { | 1312 | { |
1270 | /* | 1313 | /* |
1271 | * Prove that the new dependency does not connect a hardirq-safe | 1314 | * Prove that the new dependency does not connect a hardirq-safe |
@@ -1273,38 +1316,34 @@ check_prev_add_irq(struct task_struct *curr, struct held_lock *prev, | |||
1273 | * the backwards-subgraph starting at <prev>, and the | 1316 | * the backwards-subgraph starting at <prev>, and the |
1274 | * forwards-subgraph starting at <next>: | 1317 | * forwards-subgraph starting at <next>: |
1275 | */ | 1318 | */ |
1276 | if (!check_usage(curr, prev, next, LOCK_USED_IN_HARDIRQ, | 1319 | if (!check_usage(curr, prev, next, bit, |
1277 | LOCK_ENABLED_HARDIRQS, "hard")) | 1320 | exclusive_bit(bit), state_name(bit))) |
1278 | return 0; | 1321 | return 0; |
1279 | 1322 | ||
1323 | bit++; /* _READ */ | ||
1324 | |||
1280 | /* | 1325 | /* |
1281 | * Prove that the new dependency does not connect a hardirq-safe-read | 1326 | * Prove that the new dependency does not connect a hardirq-safe-read |
1282 | * lock with a hardirq-unsafe lock - to achieve this we search | 1327 | * lock with a hardirq-unsafe lock - to achieve this we search |
1283 | * the backwards-subgraph starting at <prev>, and the | 1328 | * the backwards-subgraph starting at <prev>, and the |
1284 | * forwards-subgraph starting at <next>: | 1329 | * forwards-subgraph starting at <next>: |
1285 | */ | 1330 | */ |
1286 | if (!check_usage(curr, prev, next, LOCK_USED_IN_HARDIRQ_READ, | 1331 | if (!check_usage(curr, prev, next, bit, |
1287 | LOCK_ENABLED_HARDIRQS, "hard-read")) | 1332 | exclusive_bit(bit), state_name(bit))) |
1288 | return 0; | 1333 | return 0; |
1289 | 1334 | ||
1290 | /* | 1335 | return 1; |
1291 | * Prove that the new dependency does not connect a softirq-safe | 1336 | } |
1292 | * lock with a softirq-unsafe lock - to achieve this we search | 1337 | |
1293 | * the backwards-subgraph starting at <prev>, and the | 1338 | static int |
1294 | * forwards-subgraph starting at <next>: | 1339 | check_prev_add_irq(struct task_struct *curr, struct held_lock *prev, |
1295 | */ | 1340 | struct held_lock *next) |
1296 | if (!check_usage(curr, prev, next, LOCK_USED_IN_SOFTIRQ, | 1341 | { |
1297 | LOCK_ENABLED_SOFTIRQS, "soft")) | 1342 | #define LOCKDEP_STATE(__STATE) \ |
1298 | return 0; | 1343 | if (!check_irq_usage(curr, prev, next, LOCK_USED_IN_##__STATE)) \ |
1299 | /* | ||
1300 | * Prove that the new dependency does not connect a softirq-safe-read | ||
1301 | * lock with a softirq-unsafe lock - to achieve this we search | ||
1302 | * the backwards-subgraph starting at <prev>, and the | ||
1303 | * forwards-subgraph starting at <next>: | ||
1304 | */ | ||
1305 | if (!check_usage(curr, prev, next, LOCK_USED_IN_SOFTIRQ_READ, | ||
1306 | LOCK_ENABLED_SOFTIRQS, "soft")) | ||
1307 | return 0; | 1344 | return 0; |
1345 | #include "lockdep_states.h" | ||
1346 | #undef LOCKDEP_STATE | ||
1308 | 1347 | ||
1309 | return 1; | 1348 | return 1; |
1310 | } | 1349 | } |
@@ -1933,7 +1972,7 @@ void print_irqtrace_events(struct task_struct *curr) | |||
1933 | print_ip_sym(curr->softirq_disable_ip); | 1972 | print_ip_sym(curr->softirq_disable_ip); |
1934 | } | 1973 | } |
1935 | 1974 | ||
1936 | static int hardirq_verbose(struct lock_class *class) | 1975 | static int HARDIRQ_verbose(struct lock_class *class) |
1937 | { | 1976 | { |
1938 | #if HARDIRQ_VERBOSE | 1977 | #if HARDIRQ_VERBOSE |
1939 | return class_filter(class); | 1978 | return class_filter(class); |
@@ -1941,7 +1980,7 @@ static int hardirq_verbose(struct lock_class *class) | |||
1941 | return 0; | 1980 | return 0; |
1942 | } | 1981 | } |
1943 | 1982 | ||
1944 | static int softirq_verbose(struct lock_class *class) | 1983 | static int SOFTIRQ_verbose(struct lock_class *class) |
1945 | { | 1984 | { |
1946 | #if SOFTIRQ_VERBOSE | 1985 | #if SOFTIRQ_VERBOSE |
1947 | return class_filter(class); | 1986 | return class_filter(class); |
@@ -1949,185 +1988,94 @@ static int softirq_verbose(struct lock_class *class) | |||
1949 | return 0; | 1988 | return 0; |
1950 | } | 1989 | } |
1951 | 1990 | ||
1991 | static int RECLAIM_FS_verbose(struct lock_class *class) | ||
1992 | { | ||
1993 | #if RECLAIM_VERBOSE | ||
1994 | return class_filter(class); | ||
1995 | #endif | ||
1996 | return 0; | ||
1997 | } | ||
1998 | |||
1952 | #define STRICT_READ_CHECKS 1 | 1999 | #define STRICT_READ_CHECKS 1 |
1953 | 2000 | ||
1954 | static int mark_lock_irq(struct task_struct *curr, struct held_lock *this, | 2001 | static int (*state_verbose_f[])(struct lock_class *class) = { |
1955 | enum lock_usage_bit new_bit) | 2002 | #define LOCKDEP_STATE(__STATE) \ |
2003 | __STATE##_verbose, | ||
2004 | #include "lockdep_states.h" | ||
2005 | #undef LOCKDEP_STATE | ||
2006 | }; | ||
2007 | |||
2008 | static inline int state_verbose(enum lock_usage_bit bit, | ||
2009 | struct lock_class *class) | ||
1956 | { | 2010 | { |
1957 | int ret = 1; | 2011 | return state_verbose_f[bit >> 2](class); |
2012 | } | ||
1958 | 2013 | ||
1959 | switch(new_bit) { | 2014 | typedef int (*check_usage_f)(struct task_struct *, struct held_lock *, |
1960 | case LOCK_USED_IN_HARDIRQ: | 2015 | enum lock_usage_bit bit, const char *name); |
1961 | if (!valid_state(curr, this, new_bit, LOCK_ENABLED_HARDIRQS)) | 2016 | |
1962 | return 0; | 2017 | static int |
1963 | if (!valid_state(curr, this, new_bit, | 2018 | mark_lock_irq(struct task_struct *curr, struct held_lock *this, int new_bit) |
1964 | LOCK_ENABLED_HARDIRQS_READ)) | 2019 | { |
1965 | return 0; | 2020 | int excl_bit = exclusive_bit(new_bit); |
1966 | /* | 2021 | int read = new_bit & 1; |
1967 | * just marked it hardirq-safe, check that this lock | 2022 | int dir = new_bit & 2; |
1968 | * took no hardirq-unsafe lock in the past: | 2023 | |
1969 | */ | 2024 | /* |
1970 | if (!check_usage_forwards(curr, this, | 2025 | * mark USED_IN has to look forwards -- to ensure no dependency |
1971 | LOCK_ENABLED_HARDIRQS, "hard")) | 2026 | * has ENABLED state, which would allow recursion deadlocks. |
1972 | return 0; | 2027 | * |
1973 | #if STRICT_READ_CHECKS | 2028 | * mark ENABLED has to look backwards -- to ensure no dependee |
1974 | /* | 2029 | * has USED_IN state, which, again, would allow recursion deadlocks. |
1975 | * just marked it hardirq-safe, check that this lock | 2030 | */ |
1976 | * took no hardirq-unsafe-read lock in the past: | 2031 | check_usage_f usage = dir ? |
1977 | */ | 2032 | check_usage_backwards : check_usage_forwards; |
1978 | if (!check_usage_forwards(curr, this, | 2033 | |
1979 | LOCK_ENABLED_HARDIRQS_READ, "hard-read")) | 2034 | /* |
1980 | return 0; | 2035 | * Validate that this particular lock does not have conflicting |
1981 | #endif | 2036 | * usage states. |
1982 | if (hardirq_verbose(hlock_class(this))) | 2037 | */ |
1983 | ret = 2; | 2038 | if (!valid_state(curr, this, new_bit, excl_bit)) |
1984 | break; | 2039 | return 0; |
1985 | case LOCK_USED_IN_SOFTIRQ: | 2040 | |
1986 | if (!valid_state(curr, this, new_bit, LOCK_ENABLED_SOFTIRQS)) | 2041 | /* |
1987 | return 0; | 2042 | * Validate that the lock dependencies don't have conflicting usage |
1988 | if (!valid_state(curr, this, new_bit, | 2043 | * states. |
1989 | LOCK_ENABLED_SOFTIRQS_READ)) | 2044 | */ |
1990 | return 0; | 2045 | if ((!read || !dir || STRICT_READ_CHECKS) && |
1991 | /* | 2046 | !usage(curr, this, excl_bit, state_name(new_bit))) |
1992 | * just marked it softirq-safe, check that this lock | 2047 | return 0; |
1993 | * took no softirq-unsafe lock in the past: | 2048 | |
1994 | */ | 2049 | /* |
1995 | if (!check_usage_forwards(curr, this, | 2050 | * Check for read in write conflicts |
1996 | LOCK_ENABLED_SOFTIRQS, "soft")) | 2051 | */ |
1997 | return 0; | 2052 | if (!read) { |
1998 | #if STRICT_READ_CHECKS | 2053 | if (!valid_state(curr, this, new_bit, excl_bit + 1)) |
1999 | /* | ||
2000 | * just marked it softirq-safe, check that this lock | ||
2001 | * took no softirq-unsafe-read lock in the past: | ||
2002 | */ | ||
2003 | if (!check_usage_forwards(curr, this, | ||
2004 | LOCK_ENABLED_SOFTIRQS_READ, "soft-read")) | ||
2005 | return 0; | ||
2006 | #endif | ||
2007 | if (softirq_verbose(hlock_class(this))) | ||
2008 | ret = 2; | ||
2009 | break; | ||
2010 | case LOCK_USED_IN_HARDIRQ_READ: | ||
2011 | if (!valid_state(curr, this, new_bit, LOCK_ENABLED_HARDIRQS)) | ||
2012 | return 0; | ||
2013 | /* | ||
2014 | * just marked it hardirq-read-safe, check that this lock | ||
2015 | * took no hardirq-unsafe lock in the past: | ||
2016 | */ | ||
2017 | if (!check_usage_forwards(curr, this, | ||
2018 | LOCK_ENABLED_HARDIRQS, "hard")) | ||
2019 | return 0; | ||
2020 | if (hardirq_verbose(hlock_class(this))) | ||
2021 | ret = 2; | ||
2022 | break; | ||
2023 | case LOCK_USED_IN_SOFTIRQ_READ: | ||
2024 | if (!valid_state(curr, this, new_bit, LOCK_ENABLED_SOFTIRQS)) | ||
2025 | return 0; | ||
2026 | /* | ||
2027 | * just marked it softirq-read-safe, check that this lock | ||
2028 | * took no softirq-unsafe lock in the past: | ||
2029 | */ | ||
2030 | if (!check_usage_forwards(curr, this, | ||
2031 | LOCK_ENABLED_SOFTIRQS, "soft")) | ||
2032 | return 0; | ||
2033 | if (softirq_verbose(hlock_class(this))) | ||
2034 | ret = 2; | ||
2035 | break; | ||
2036 | case LOCK_ENABLED_HARDIRQS: | ||
2037 | if (!valid_state(curr, this, new_bit, LOCK_USED_IN_HARDIRQ)) | ||
2038 | return 0; | ||
2039 | if (!valid_state(curr, this, new_bit, | ||
2040 | LOCK_USED_IN_HARDIRQ_READ)) | ||
2041 | return 0; | ||
2042 | /* | ||
2043 | * just marked it hardirq-unsafe, check that no hardirq-safe | ||
2044 | * lock in the system ever took it in the past: | ||
2045 | */ | ||
2046 | if (!check_usage_backwards(curr, this, | ||
2047 | LOCK_USED_IN_HARDIRQ, "hard")) | ||
2048 | return 0; | ||
2049 | #if STRICT_READ_CHECKS | ||
2050 | /* | ||
2051 | * just marked it hardirq-unsafe, check that no | ||
2052 | * hardirq-safe-read lock in the system ever took | ||
2053 | * it in the past: | ||
2054 | */ | ||
2055 | if (!check_usage_backwards(curr, this, | ||
2056 | LOCK_USED_IN_HARDIRQ_READ, "hard-read")) | ||
2057 | return 0; | ||
2058 | #endif | ||
2059 | if (hardirq_verbose(hlock_class(this))) | ||
2060 | ret = 2; | ||
2061 | break; | ||
2062 | case LOCK_ENABLED_SOFTIRQS: | ||
2063 | if (!valid_state(curr, this, new_bit, LOCK_USED_IN_SOFTIRQ)) | ||
2064 | return 0; | ||
2065 | if (!valid_state(curr, this, new_bit, | ||
2066 | LOCK_USED_IN_SOFTIRQ_READ)) | ||
2067 | return 0; | ||
2068 | /* | ||
2069 | * just marked it softirq-unsafe, check that no softirq-safe | ||
2070 | * lock in the system ever took it in the past: | ||
2071 | */ | ||
2072 | if (!check_usage_backwards(curr, this, | ||
2073 | LOCK_USED_IN_SOFTIRQ, "soft")) | ||
2074 | return 0; | ||
2075 | #if STRICT_READ_CHECKS | ||
2076 | /* | ||
2077 | * just marked it softirq-unsafe, check that no | ||
2078 | * softirq-safe-read lock in the system ever took | ||
2079 | * it in the past: | ||
2080 | */ | ||
2081 | if (!check_usage_backwards(curr, this, | ||
2082 | LOCK_USED_IN_SOFTIRQ_READ, "soft-read")) | ||
2083 | return 0; | ||
2084 | #endif | ||
2085 | if (softirq_verbose(hlock_class(this))) | ||
2086 | ret = 2; | ||
2087 | break; | ||
2088 | case LOCK_ENABLED_HARDIRQS_READ: | ||
2089 | if (!valid_state(curr, this, new_bit, LOCK_USED_IN_HARDIRQ)) | ||
2090 | return 0; | ||
2091 | #if STRICT_READ_CHECKS | ||
2092 | /* | ||
2093 | * just marked it hardirq-read-unsafe, check that no | ||
2094 | * hardirq-safe lock in the system ever took it in the past: | ||
2095 | */ | ||
2096 | if (!check_usage_backwards(curr, this, | ||
2097 | LOCK_USED_IN_HARDIRQ, "hard")) | ||
2098 | return 0; | ||
2099 | #endif | ||
2100 | if (hardirq_verbose(hlock_class(this))) | ||
2101 | ret = 2; | ||
2102 | break; | ||
2103 | case LOCK_ENABLED_SOFTIRQS_READ: | ||
2104 | if (!valid_state(curr, this, new_bit, LOCK_USED_IN_SOFTIRQ)) | ||
2105 | return 0; | 2054 | return 0; |
2106 | #if STRICT_READ_CHECKS | 2055 | |
2107 | /* | 2056 | if (STRICT_READ_CHECKS && |
2108 | * just marked it softirq-read-unsafe, check that no | 2057 | !usage(curr, this, excl_bit + 1, |
2109 | * softirq-safe lock in the system ever took it in the past: | 2058 | state_name(new_bit + 1))) |
2110 | */ | ||
2111 | if (!check_usage_backwards(curr, this, | ||
2112 | LOCK_USED_IN_SOFTIRQ, "soft")) | ||
2113 | return 0; | 2059 | return 0; |
2114 | #endif | ||
2115 | if (softirq_verbose(hlock_class(this))) | ||
2116 | ret = 2; | ||
2117 | break; | ||
2118 | default: | ||
2119 | WARN_ON(1); | ||
2120 | break; | ||
2121 | } | 2060 | } |
2122 | 2061 | ||
2123 | return ret; | 2062 | if (state_verbose(new_bit, hlock_class(this))) |
2063 | return 2; | ||
2064 | |||
2065 | return 1; | ||
2124 | } | 2066 | } |
2125 | 2067 | ||
2068 | enum mark_type { | ||
2069 | #define LOCKDEP_STATE(__STATE) __STATE, | ||
2070 | #include "lockdep_states.h" | ||
2071 | #undef LOCKDEP_STATE | ||
2072 | }; | ||
2073 | |||
2126 | /* | 2074 | /* |
2127 | * Mark all held locks with a usage bit: | 2075 | * Mark all held locks with a usage bit: |
2128 | */ | 2076 | */ |
2129 | static int | 2077 | static int |
2130 | mark_held_locks(struct task_struct *curr, int hardirq) | 2078 | mark_held_locks(struct task_struct *curr, enum mark_type mark) |
2131 | { | 2079 | { |
2132 | enum lock_usage_bit usage_bit; | 2080 | enum lock_usage_bit usage_bit; |
2133 | struct held_lock *hlock; | 2081 | struct held_lock *hlock; |
@@ -2136,17 +2084,12 @@ mark_held_locks(struct task_struct *curr, int hardirq) | |||
2136 | for (i = 0; i < curr->lockdep_depth; i++) { | 2084 | for (i = 0; i < curr->lockdep_depth; i++) { |
2137 | hlock = curr->held_locks + i; | 2085 | hlock = curr->held_locks + i; |
2138 | 2086 | ||
2139 | if (hardirq) { | 2087 | usage_bit = 2 + (mark << 2); /* ENABLED */ |
2140 | if (hlock->read) | 2088 | if (hlock->read) |
2141 | usage_bit = LOCK_ENABLED_HARDIRQS_READ; | 2089 | usage_bit += 1; /* READ */ |
2142 | else | 2090 | |
2143 | usage_bit = LOCK_ENABLED_HARDIRQS; | 2091 | BUG_ON(usage_bit >= LOCK_USAGE_STATES); |
2144 | } else { | 2092 | |
2145 | if (hlock->read) | ||
2146 | usage_bit = LOCK_ENABLED_SOFTIRQS_READ; | ||
2147 | else | ||
2148 | usage_bit = LOCK_ENABLED_SOFTIRQS; | ||
2149 | } | ||
2150 | if (!mark_lock(curr, hlock, usage_bit)) | 2093 | if (!mark_lock(curr, hlock, usage_bit)) |
2151 | return 0; | 2094 | return 0; |
2152 | } | 2095 | } |
@@ -2200,7 +2143,7 @@ void trace_hardirqs_on_caller(unsigned long ip) | |||
2200 | * We are going to turn hardirqs on, so set the | 2143 | * We are going to turn hardirqs on, so set the |
2201 | * usage bit for all held locks: | 2144 | * usage bit for all held locks: |
2202 | */ | 2145 | */ |
2203 | if (!mark_held_locks(curr, 1)) | 2146 | if (!mark_held_locks(curr, HARDIRQ)) |
2204 | return; | 2147 | return; |
2205 | /* | 2148 | /* |
2206 | * If we have softirqs enabled, then set the usage | 2149 | * If we have softirqs enabled, then set the usage |
@@ -2208,7 +2151,7 @@ void trace_hardirqs_on_caller(unsigned long ip) | |||
2208 | * this bit from being set before) | 2151 | * this bit from being set before) |
2209 | */ | 2152 | */ |
2210 | if (curr->softirqs_enabled) | 2153 | if (curr->softirqs_enabled) |
2211 | if (!mark_held_locks(curr, 0)) | 2154 | if (!mark_held_locks(curr, SOFTIRQ)) |
2212 | return; | 2155 | return; |
2213 | 2156 | ||
2214 | curr->hardirq_enable_ip = ip; | 2157 | curr->hardirq_enable_ip = ip; |
@@ -2288,7 +2231,7 @@ void trace_softirqs_on(unsigned long ip) | |||
2288 | * enabled too: | 2231 | * enabled too: |
2289 | */ | 2232 | */ |
2290 | if (curr->hardirqs_enabled) | 2233 | if (curr->hardirqs_enabled) |
2291 | mark_held_locks(curr, 0); | 2234 | mark_held_locks(curr, SOFTIRQ); |
2292 | } | 2235 | } |
2293 | 2236 | ||
2294 | /* | 2237 | /* |
@@ -2317,6 +2260,48 @@ void trace_softirqs_off(unsigned long ip) | |||
2317 | debug_atomic_inc(&redundant_softirqs_off); | 2260 | debug_atomic_inc(&redundant_softirqs_off); |
2318 | } | 2261 | } |
2319 | 2262 | ||
2263 | static void __lockdep_trace_alloc(gfp_t gfp_mask, unsigned long flags) | ||
2264 | { | ||
2265 | struct task_struct *curr = current; | ||
2266 | |||
2267 | if (unlikely(!debug_locks)) | ||
2268 | return; | ||
2269 | |||
2270 | /* no reclaim without waiting on it */ | ||
2271 | if (!(gfp_mask & __GFP_WAIT)) | ||
2272 | return; | ||
2273 | |||
2274 | /* this guy won't enter reclaim */ | ||
2275 | if ((curr->flags & PF_MEMALLOC) && !(gfp_mask & __GFP_NOMEMALLOC)) | ||
2276 | return; | ||
2277 | |||
2278 | /* We're only interested __GFP_FS allocations for now */ | ||
2279 | if (!(gfp_mask & __GFP_FS)) | ||
2280 | return; | ||
2281 | |||
2282 | if (DEBUG_LOCKS_WARN_ON(irqs_disabled_flags(flags))) | ||
2283 | return; | ||
2284 | |||
2285 | mark_held_locks(curr, RECLAIM_FS); | ||
2286 | } | ||
2287 | |||
2288 | static void check_flags(unsigned long flags); | ||
2289 | |||
2290 | void lockdep_trace_alloc(gfp_t gfp_mask) | ||
2291 | { | ||
2292 | unsigned long flags; | ||
2293 | |||
2294 | if (unlikely(current->lockdep_recursion)) | ||
2295 | return; | ||
2296 | |||
2297 | raw_local_irq_save(flags); | ||
2298 | check_flags(flags); | ||
2299 | current->lockdep_recursion = 1; | ||
2300 | __lockdep_trace_alloc(gfp_mask, flags); | ||
2301 | current->lockdep_recursion = 0; | ||
2302 | raw_local_irq_restore(flags); | ||
2303 | } | ||
2304 | |||
2320 | static int mark_irqflags(struct task_struct *curr, struct held_lock *hlock) | 2305 | static int mark_irqflags(struct task_struct *curr, struct held_lock *hlock) |
2321 | { | 2306 | { |
2322 | /* | 2307 | /* |
@@ -2345,19 +2330,35 @@ static int mark_irqflags(struct task_struct *curr, struct held_lock *hlock) | |||
2345 | if (!hlock->hardirqs_off) { | 2330 | if (!hlock->hardirqs_off) { |
2346 | if (hlock->read) { | 2331 | if (hlock->read) { |
2347 | if (!mark_lock(curr, hlock, | 2332 | if (!mark_lock(curr, hlock, |
2348 | LOCK_ENABLED_HARDIRQS_READ)) | 2333 | LOCK_ENABLED_HARDIRQ_READ)) |
2349 | return 0; | 2334 | return 0; |
2350 | if (curr->softirqs_enabled) | 2335 | if (curr->softirqs_enabled) |
2351 | if (!mark_lock(curr, hlock, | 2336 | if (!mark_lock(curr, hlock, |
2352 | LOCK_ENABLED_SOFTIRQS_READ)) | 2337 | LOCK_ENABLED_SOFTIRQ_READ)) |
2353 | return 0; | 2338 | return 0; |
2354 | } else { | 2339 | } else { |
2355 | if (!mark_lock(curr, hlock, | 2340 | if (!mark_lock(curr, hlock, |
2356 | LOCK_ENABLED_HARDIRQS)) | 2341 | LOCK_ENABLED_HARDIRQ)) |
2357 | return 0; | 2342 | return 0; |
2358 | if (curr->softirqs_enabled) | 2343 | if (curr->softirqs_enabled) |
2359 | if (!mark_lock(curr, hlock, | 2344 | if (!mark_lock(curr, hlock, |
2360 | LOCK_ENABLED_SOFTIRQS)) | 2345 | LOCK_ENABLED_SOFTIRQ)) |
2346 | return 0; | ||
2347 | } | ||
2348 | } | ||
2349 | |||
2350 | /* | ||
2351 | * We reuse the irq context infrastructure more broadly as a general | ||
2352 | * context checking code. This tests GFP_FS recursion (a lock taken | ||
2353 | * during reclaim for a GFP_FS allocation is held over a GFP_FS | ||
2354 | * allocation). | ||
2355 | */ | ||
2356 | if (!hlock->trylock && (curr->lockdep_reclaim_gfp & __GFP_FS)) { | ||
2357 | if (hlock->read) { | ||
2358 | if (!mark_lock(curr, hlock, LOCK_USED_IN_RECLAIM_FS_READ)) | ||
2359 | return 0; | ||
2360 | } else { | ||
2361 | if (!mark_lock(curr, hlock, LOCK_USED_IN_RECLAIM_FS)) | ||
2361 | return 0; | 2362 | return 0; |
2362 | } | 2363 | } |
2363 | } | 2364 | } |
@@ -2412,6 +2413,10 @@ static inline int separate_irq_context(struct task_struct *curr, | |||
2412 | return 0; | 2413 | return 0; |
2413 | } | 2414 | } |
2414 | 2415 | ||
2416 | void lockdep_trace_alloc(gfp_t gfp_mask) | ||
2417 | { | ||
2418 | } | ||
2419 | |||
2415 | #endif | 2420 | #endif |
2416 | 2421 | ||
2417 | /* | 2422 | /* |
@@ -2445,14 +2450,13 @@ static int mark_lock(struct task_struct *curr, struct held_lock *this, | |||
2445 | return 0; | 2450 | return 0; |
2446 | 2451 | ||
2447 | switch (new_bit) { | 2452 | switch (new_bit) { |
2448 | case LOCK_USED_IN_HARDIRQ: | 2453 | #define LOCKDEP_STATE(__STATE) \ |
2449 | case LOCK_USED_IN_SOFTIRQ: | 2454 | case LOCK_USED_IN_##__STATE: \ |
2450 | case LOCK_USED_IN_HARDIRQ_READ: | 2455 | case LOCK_USED_IN_##__STATE##_READ: \ |
2451 | case LOCK_USED_IN_SOFTIRQ_READ: | 2456 | case LOCK_ENABLED_##__STATE: \ |
2452 | case LOCK_ENABLED_HARDIRQS: | 2457 | case LOCK_ENABLED_##__STATE##_READ: |
2453 | case LOCK_ENABLED_SOFTIRQS: | 2458 | #include "lockdep_states.h" |
2454 | case LOCK_ENABLED_HARDIRQS_READ: | 2459 | #undef LOCKDEP_STATE |
2455 | case LOCK_ENABLED_SOFTIRQS_READ: | ||
2456 | ret = mark_lock_irq(curr, this, new_bit); | 2460 | ret = mark_lock_irq(curr, this, new_bit); |
2457 | if (!ret) | 2461 | if (!ret) |
2458 | return 0; | 2462 | return 0; |
@@ -2966,6 +2970,16 @@ void lock_release(struct lockdep_map *lock, int nested, | |||
2966 | } | 2970 | } |
2967 | EXPORT_SYMBOL_GPL(lock_release); | 2971 | EXPORT_SYMBOL_GPL(lock_release); |
2968 | 2972 | ||
2973 | void lockdep_set_current_reclaim_state(gfp_t gfp_mask) | ||
2974 | { | ||
2975 | current->lockdep_reclaim_gfp = gfp_mask; | ||
2976 | } | ||
2977 | |||
2978 | void lockdep_clear_current_reclaim_state(void) | ||
2979 | { | ||
2980 | current->lockdep_reclaim_gfp = 0; | ||
2981 | } | ||
2982 | |||
2969 | #ifdef CONFIG_LOCK_STAT | 2983 | #ifdef CONFIG_LOCK_STAT |
2970 | static int | 2984 | static int |
2971 | print_lock_contention_bug(struct task_struct *curr, struct lockdep_map *lock, | 2985 | print_lock_contention_bug(struct task_struct *curr, struct lockdep_map *lock, |