diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-03-04 12:49:19 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-03-04 12:49:19 -0500 |
commit | 28b1bd1cbc33cae95a309691d814399a69cf3070 (patch) | |
tree | 6474d10332662f5302be0df8527c9e9e31e32a95 /kernel/lockdep.c | |
parent | 2602c3ba4508f528db024c1d209256513ea05de6 (diff) | |
parent | 1075414b06109a99b0e87601e84c74a95bd45681 (diff) |
Merge branch 'core/locking' into tracing/ftrace
Diffstat (limited to 'kernel/lockdep.c')
-rw-r--r-- | kernel/lockdep.c | 514 |
1 files changed, 256 insertions, 258 deletions
diff --git a/kernel/lockdep.c b/kernel/lockdep.c index 06b0c3568f0b..02014f7ccc86 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 | } |
@@ -1861,9 +1900,9 @@ print_irq_inversion_bug(struct task_struct *curr, struct lock_class *other, | |||
1861 | curr->comm, task_pid_nr(curr)); | 1900 | curr->comm, task_pid_nr(curr)); |
1862 | print_lock(this); | 1901 | print_lock(this); |
1863 | if (forwards) | 1902 | if (forwards) |
1864 | printk("but this lock took another, %s-irq-unsafe lock in the past:\n", irqclass); | 1903 | printk("but this lock took another, %s-unsafe lock in the past:\n", irqclass); |
1865 | else | 1904 | else |
1866 | printk("but this lock was taken by another, %s-irq-safe lock in the past:\n", irqclass); | 1905 | printk("but this lock was taken by another, %s-safe lock in the past:\n", irqclass); |
1867 | print_lock_name(other); | 1906 | print_lock_name(other); |
1868 | printk("\n\nand interrupts could create inverse lock ordering between them.\n\n"); | 1907 | printk("\n\nand interrupts could create inverse lock ordering between them.\n\n"); |
1869 | 1908 | ||
@@ -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,95 @@ 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) = { |
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) | ||
2010 | { | ||
2011 | return state_verbose_f[bit >> 2](class); | ||
2012 | } | ||
2013 | |||
2014 | typedef int (*check_usage_f)(struct task_struct *, struct held_lock *, | ||
2015 | enum lock_usage_bit bit, const char *name); | ||
2016 | |||
2017 | static int | ||
2018 | mark_lock_irq(struct task_struct *curr, struct held_lock *this, | ||
1955 | enum lock_usage_bit new_bit) | 2019 | enum lock_usage_bit new_bit) |
1956 | { | 2020 | { |
1957 | int ret = 1; | 2021 | int excl_bit = exclusive_bit(new_bit); |
2022 | int read = new_bit & 1; | ||
2023 | int dir = new_bit & 2; | ||
1958 | 2024 | ||
1959 | switch(new_bit) { | 2025 | /* |
1960 | case LOCK_USED_IN_HARDIRQ: | 2026 | * mark USED_IN has to look forwards -- to ensure no dependency |
1961 | if (!valid_state(curr, this, new_bit, LOCK_ENABLED_HARDIRQS)) | 2027 | * has ENABLED state, which would allow recursion deadlocks. |
1962 | return 0; | 2028 | * |
1963 | if (!valid_state(curr, this, new_bit, | 2029 | * mark ENABLED has to look backwards -- to ensure no dependee |
1964 | LOCK_ENABLED_HARDIRQS_READ)) | 2030 | * has USED_IN state, which, again, would allow recursion deadlocks. |
1965 | return 0; | 2031 | */ |
1966 | /* | 2032 | check_usage_f usage = dir ? |
1967 | * just marked it hardirq-safe, check that this lock | 2033 | check_usage_backwards : check_usage_forwards; |
1968 | * took no hardirq-unsafe lock in the past: | 2034 | |
1969 | */ | 2035 | /* |
1970 | if (!check_usage_forwards(curr, this, | 2036 | * Validate that this particular lock does not have conflicting |
1971 | LOCK_ENABLED_HARDIRQS, "hard")) | 2037 | * usage states. |
1972 | return 0; | 2038 | */ |
1973 | #if STRICT_READ_CHECKS | 2039 | if (!valid_state(curr, this, new_bit, excl_bit)) |
1974 | /* | 2040 | return 0; |
1975 | * just marked it hardirq-safe, check that this lock | 2041 | |
1976 | * took no hardirq-unsafe-read lock in the past: | 2042 | /* |
1977 | */ | 2043 | * Validate that the lock dependencies don't have conflicting usage |
1978 | if (!check_usage_forwards(curr, this, | 2044 | * states. |
1979 | LOCK_ENABLED_HARDIRQS_READ, "hard-read")) | 2045 | */ |
1980 | return 0; | 2046 | if ((!read || !dir || STRICT_READ_CHECKS) && |
1981 | #endif | 2047 | !usage(curr, this, excl_bit, state_name(new_bit & ~1))) |
1982 | if (hardirq_verbose(hlock_class(this))) | 2048 | return 0; |
1983 | ret = 2; | 2049 | |
1984 | break; | 2050 | /* |
1985 | case LOCK_USED_IN_SOFTIRQ: | 2051 | * Check for read in write conflicts |
1986 | if (!valid_state(curr, this, new_bit, LOCK_ENABLED_SOFTIRQS)) | 2052 | */ |
1987 | return 0; | 2053 | if (!read) { |
1988 | if (!valid_state(curr, this, new_bit, | 2054 | if (!valid_state(curr, this, new_bit, excl_bit + 1)) |
1989 | LOCK_ENABLED_SOFTIRQS_READ)) | ||
1990 | return 0; | ||
1991 | /* | ||
1992 | * just marked it softirq-safe, check that this lock | ||
1993 | * took no softirq-unsafe lock in the past: | ||
1994 | */ | ||
1995 | if (!check_usage_forwards(curr, this, | ||
1996 | LOCK_ENABLED_SOFTIRQS, "soft")) | ||
1997 | return 0; | ||
1998 | #if STRICT_READ_CHECKS | ||
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; | 2055 | return 0; |
2106 | #if STRICT_READ_CHECKS | 2056 | |
2107 | /* | 2057 | if (STRICT_READ_CHECKS && |
2108 | * just marked it softirq-read-unsafe, check that no | 2058 | !usage(curr, this, excl_bit + 1, |
2109 | * softirq-safe lock in the system ever took it in the past: | 2059 | state_name(new_bit + 1))) |
2110 | */ | ||
2111 | if (!check_usage_backwards(curr, this, | ||
2112 | LOCK_USED_IN_SOFTIRQ, "soft")) | ||
2113 | return 0; | 2060 | 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 | } | 2061 | } |
2122 | 2062 | ||
2123 | return ret; | 2063 | if (state_verbose(new_bit, hlock_class(this))) |
2064 | return 2; | ||
2065 | |||
2066 | return 1; | ||
2124 | } | 2067 | } |
2125 | 2068 | ||
2069 | enum mark_type { | ||
2070 | #define LOCKDEP_STATE(__STATE) __STATE, | ||
2071 | #include "lockdep_states.h" | ||
2072 | #undef LOCKDEP_STATE | ||
2073 | }; | ||
2074 | |||
2126 | /* | 2075 | /* |
2127 | * Mark all held locks with a usage bit: | 2076 | * Mark all held locks with a usage bit: |
2128 | */ | 2077 | */ |
2129 | static int | 2078 | static int |
2130 | mark_held_locks(struct task_struct *curr, int hardirq) | 2079 | mark_held_locks(struct task_struct *curr, enum mark_type mark) |
2131 | { | 2080 | { |
2132 | enum lock_usage_bit usage_bit; | 2081 | enum lock_usage_bit usage_bit; |
2133 | struct held_lock *hlock; | 2082 | struct held_lock *hlock; |
@@ -2136,17 +2085,12 @@ mark_held_locks(struct task_struct *curr, int hardirq) | |||
2136 | for (i = 0; i < curr->lockdep_depth; i++) { | 2085 | for (i = 0; i < curr->lockdep_depth; i++) { |
2137 | hlock = curr->held_locks + i; | 2086 | hlock = curr->held_locks + i; |
2138 | 2087 | ||
2139 | if (hardirq) { | 2088 | usage_bit = 2 + (mark << 2); /* ENABLED */ |
2140 | if (hlock->read) | 2089 | if (hlock->read) |
2141 | usage_bit = LOCK_ENABLED_HARDIRQS_READ; | 2090 | usage_bit += 1; /* READ */ |
2142 | else | 2091 | |
2143 | usage_bit = LOCK_ENABLED_HARDIRQS; | 2092 | BUG_ON(usage_bit >= LOCK_USAGE_STATES); |
2144 | } else { | 2093 | |
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)) | 2094 | if (!mark_lock(curr, hlock, usage_bit)) |
2151 | return 0; | 2095 | return 0; |
2152 | } | 2096 | } |
@@ -2200,7 +2144,7 @@ void trace_hardirqs_on_caller(unsigned long ip) | |||
2200 | * We are going to turn hardirqs on, so set the | 2144 | * We are going to turn hardirqs on, so set the |
2201 | * usage bit for all held locks: | 2145 | * usage bit for all held locks: |
2202 | */ | 2146 | */ |
2203 | if (!mark_held_locks(curr, 1)) | 2147 | if (!mark_held_locks(curr, HARDIRQ)) |
2204 | return; | 2148 | return; |
2205 | /* | 2149 | /* |
2206 | * If we have softirqs enabled, then set the usage | 2150 | * If we have softirqs enabled, then set the usage |
@@ -2208,7 +2152,7 @@ void trace_hardirqs_on_caller(unsigned long ip) | |||
2208 | * this bit from being set before) | 2152 | * this bit from being set before) |
2209 | */ | 2153 | */ |
2210 | if (curr->softirqs_enabled) | 2154 | if (curr->softirqs_enabled) |
2211 | if (!mark_held_locks(curr, 0)) | 2155 | if (!mark_held_locks(curr, SOFTIRQ)) |
2212 | return; | 2156 | return; |
2213 | 2157 | ||
2214 | curr->hardirq_enable_ip = ip; | 2158 | curr->hardirq_enable_ip = ip; |
@@ -2288,7 +2232,7 @@ void trace_softirqs_on(unsigned long ip) | |||
2288 | * enabled too: | 2232 | * enabled too: |
2289 | */ | 2233 | */ |
2290 | if (curr->hardirqs_enabled) | 2234 | if (curr->hardirqs_enabled) |
2291 | mark_held_locks(curr, 0); | 2235 | mark_held_locks(curr, SOFTIRQ); |
2292 | } | 2236 | } |
2293 | 2237 | ||
2294 | /* | 2238 | /* |
@@ -2317,6 +2261,31 @@ void trace_softirqs_off(unsigned long ip) | |||
2317 | debug_atomic_inc(&redundant_softirqs_off); | 2261 | debug_atomic_inc(&redundant_softirqs_off); |
2318 | } | 2262 | } |
2319 | 2263 | ||
2264 | void lockdep_trace_alloc(gfp_t gfp_mask) | ||
2265 | { | ||
2266 | struct task_struct *curr = current; | ||
2267 | |||
2268 | if (unlikely(!debug_locks)) | ||
2269 | return; | ||
2270 | |||
2271 | /* no reclaim without waiting on it */ | ||
2272 | if (!(gfp_mask & __GFP_WAIT)) | ||
2273 | return; | ||
2274 | |||
2275 | /* this guy won't enter reclaim */ | ||
2276 | if ((curr->flags & PF_MEMALLOC) && !(gfp_mask & __GFP_NOMEMALLOC)) | ||
2277 | return; | ||
2278 | |||
2279 | /* We're only interested __GFP_FS allocations for now */ | ||
2280 | if (!(gfp_mask & __GFP_FS)) | ||
2281 | return; | ||
2282 | |||
2283 | if (DEBUG_LOCKS_WARN_ON(irqs_disabled())) | ||
2284 | return; | ||
2285 | |||
2286 | mark_held_locks(curr, RECLAIM_FS); | ||
2287 | } | ||
2288 | |||
2320 | static int mark_irqflags(struct task_struct *curr, struct held_lock *hlock) | 2289 | static int mark_irqflags(struct task_struct *curr, struct held_lock *hlock) |
2321 | { | 2290 | { |
2322 | /* | 2291 | /* |
@@ -2345,19 +2314,35 @@ static int mark_irqflags(struct task_struct *curr, struct held_lock *hlock) | |||
2345 | if (!hlock->hardirqs_off) { | 2314 | if (!hlock->hardirqs_off) { |
2346 | if (hlock->read) { | 2315 | if (hlock->read) { |
2347 | if (!mark_lock(curr, hlock, | 2316 | if (!mark_lock(curr, hlock, |
2348 | LOCK_ENABLED_HARDIRQS_READ)) | 2317 | LOCK_ENABLED_HARDIRQ_READ)) |
2349 | return 0; | 2318 | return 0; |
2350 | if (curr->softirqs_enabled) | 2319 | if (curr->softirqs_enabled) |
2351 | if (!mark_lock(curr, hlock, | 2320 | if (!mark_lock(curr, hlock, |
2352 | LOCK_ENABLED_SOFTIRQS_READ)) | 2321 | LOCK_ENABLED_SOFTIRQ_READ)) |
2353 | return 0; | 2322 | return 0; |
2354 | } else { | 2323 | } else { |
2355 | if (!mark_lock(curr, hlock, | 2324 | if (!mark_lock(curr, hlock, |
2356 | LOCK_ENABLED_HARDIRQS)) | 2325 | LOCK_ENABLED_HARDIRQ)) |
2357 | return 0; | 2326 | return 0; |
2358 | if (curr->softirqs_enabled) | 2327 | if (curr->softirqs_enabled) |
2359 | if (!mark_lock(curr, hlock, | 2328 | if (!mark_lock(curr, hlock, |
2360 | LOCK_ENABLED_SOFTIRQS)) | 2329 | LOCK_ENABLED_SOFTIRQ)) |
2330 | return 0; | ||
2331 | } | ||
2332 | } | ||
2333 | |||
2334 | /* | ||
2335 | * We reuse the irq context infrastructure more broadly as a general | ||
2336 | * context checking code. This tests GFP_FS recursion (a lock taken | ||
2337 | * during reclaim for a GFP_FS allocation is held over a GFP_FS | ||
2338 | * allocation). | ||
2339 | */ | ||
2340 | if (!hlock->trylock && (curr->lockdep_reclaim_gfp & __GFP_FS)) { | ||
2341 | if (hlock->read) { | ||
2342 | if (!mark_lock(curr, hlock, LOCK_USED_IN_RECLAIM_FS_READ)) | ||
2343 | return 0; | ||
2344 | } else { | ||
2345 | if (!mark_lock(curr, hlock, LOCK_USED_IN_RECLAIM_FS)) | ||
2361 | return 0; | 2346 | return 0; |
2362 | } | 2347 | } |
2363 | } | 2348 | } |
@@ -2412,6 +2397,10 @@ static inline int separate_irq_context(struct task_struct *curr, | |||
2412 | return 0; | 2397 | return 0; |
2413 | } | 2398 | } |
2414 | 2399 | ||
2400 | void lockdep_trace_alloc(gfp_t gfp_mask) | ||
2401 | { | ||
2402 | } | ||
2403 | |||
2415 | #endif | 2404 | #endif |
2416 | 2405 | ||
2417 | /* | 2406 | /* |
@@ -2445,14 +2434,13 @@ static int mark_lock(struct task_struct *curr, struct held_lock *this, | |||
2445 | return 0; | 2434 | return 0; |
2446 | 2435 | ||
2447 | switch (new_bit) { | 2436 | switch (new_bit) { |
2448 | case LOCK_USED_IN_HARDIRQ: | 2437 | #define LOCKDEP_STATE(__STATE) \ |
2449 | case LOCK_USED_IN_SOFTIRQ: | 2438 | case LOCK_USED_IN_##__STATE: \ |
2450 | case LOCK_USED_IN_HARDIRQ_READ: | 2439 | case LOCK_USED_IN_##__STATE##_READ: \ |
2451 | case LOCK_USED_IN_SOFTIRQ_READ: | 2440 | case LOCK_ENABLED_##__STATE: \ |
2452 | case LOCK_ENABLED_HARDIRQS: | 2441 | case LOCK_ENABLED_##__STATE##_READ: |
2453 | case LOCK_ENABLED_SOFTIRQS: | 2442 | #include "lockdep_states.h" |
2454 | case LOCK_ENABLED_HARDIRQS_READ: | 2443 | #undef LOCKDEP_STATE |
2455 | case LOCK_ENABLED_SOFTIRQS_READ: | ||
2456 | ret = mark_lock_irq(curr, this, new_bit); | 2444 | ret = mark_lock_irq(curr, this, new_bit); |
2457 | if (!ret) | 2445 | if (!ret) |
2458 | return 0; | 2446 | return 0; |
@@ -2966,6 +2954,16 @@ void lock_release(struct lockdep_map *lock, int nested, | |||
2966 | } | 2954 | } |
2967 | EXPORT_SYMBOL_GPL(lock_release); | 2955 | EXPORT_SYMBOL_GPL(lock_release); |
2968 | 2956 | ||
2957 | void lockdep_set_current_reclaim_state(gfp_t gfp_mask) | ||
2958 | { | ||
2959 | current->lockdep_reclaim_gfp = gfp_mask; | ||
2960 | } | ||
2961 | |||
2962 | void lockdep_clear_current_reclaim_state(void) | ||
2963 | { | ||
2964 | current->lockdep_reclaim_gfp = 0; | ||
2965 | } | ||
2966 | |||
2969 | #ifdef CONFIG_LOCK_STAT | 2967 | #ifdef CONFIG_LOCK_STAT |
2970 | static int | 2968 | static int |
2971 | print_lock_contention_bug(struct task_struct *curr, struct lockdep_map *lock, | 2969 | print_lock_contention_bug(struct task_struct *curr, struct lockdep_map *lock, |