diff options
Diffstat (limited to 'kernel/lockdep.c')
-rw-r--r-- | kernel/lockdep.c | 229 |
1 files changed, 217 insertions, 12 deletions
diff --git a/kernel/lockdep.c b/kernel/lockdep.c index 06b0c3568f0b..977f940fd562 100644 --- a/kernel/lockdep.c +++ b/kernel/lockdep.c | |||
@@ -310,12 +310,14 @@ EXPORT_SYMBOL(lockdep_on); | |||
310 | #if VERBOSE | 310 | #if VERBOSE |
311 | # define HARDIRQ_VERBOSE 1 | 311 | # define HARDIRQ_VERBOSE 1 |
312 | # define SOFTIRQ_VERBOSE 1 | 312 | # define SOFTIRQ_VERBOSE 1 |
313 | # define RECLAIM_VERBOSE 1 | ||
313 | #else | 314 | #else |
314 | # define HARDIRQ_VERBOSE 0 | 315 | # define HARDIRQ_VERBOSE 0 |
315 | # define SOFTIRQ_VERBOSE 0 | 316 | # define SOFTIRQ_VERBOSE 0 |
317 | # define RECLAIM_VERBOSE 0 | ||
316 | #endif | 318 | #endif |
317 | 319 | ||
318 | #if VERBOSE || HARDIRQ_VERBOSE || SOFTIRQ_VERBOSE | 320 | #if VERBOSE || HARDIRQ_VERBOSE || SOFTIRQ_VERBOSE || RECLAIM_VERBOSE |
319 | /* | 321 | /* |
320 | * Quick filtering for interesting events: | 322 | * Quick filtering for interesting events: |
321 | */ | 323 | */ |
@@ -454,6 +456,10 @@ static const char *usage_str[] = | |||
454 | [LOCK_USED_IN_SOFTIRQ_READ] = "in-softirq-R", | 456 | [LOCK_USED_IN_SOFTIRQ_READ] = "in-softirq-R", |
455 | [LOCK_ENABLED_SOFTIRQS_READ] = "softirq-on-R", | 457 | [LOCK_ENABLED_SOFTIRQS_READ] = "softirq-on-R", |
456 | [LOCK_ENABLED_HARDIRQS_READ] = "hardirq-on-R", | 458 | [LOCK_ENABLED_HARDIRQS_READ] = "hardirq-on-R", |
459 | [LOCK_USED_IN_RECLAIM_FS] = "in-reclaim-W", | ||
460 | [LOCK_USED_IN_RECLAIM_FS_READ] = "in-reclaim-R", | ||
461 | [LOCK_HELD_OVER_RECLAIM_FS] = "ov-reclaim-W", | ||
462 | [LOCK_HELD_OVER_RECLAIM_FS_READ] = "ov-reclaim-R", | ||
457 | }; | 463 | }; |
458 | 464 | ||
459 | const char * __get_key_name(struct lockdep_subclass_key *key, char *str) | 465 | const char * __get_key_name(struct lockdep_subclass_key *key, char *str) |
@@ -462,9 +468,10 @@ const char * __get_key_name(struct lockdep_subclass_key *key, char *str) | |||
462 | } | 468 | } |
463 | 469 | ||
464 | void | 470 | void |
465 | get_usage_chars(struct lock_class *class, char *c1, char *c2, char *c3, char *c4) | 471 | get_usage_chars(struct lock_class *class, char *c1, char *c2, char *c3, |
472 | char *c4, char *c5, char *c6) | ||
466 | { | 473 | { |
467 | *c1 = '.', *c2 = '.', *c3 = '.', *c4 = '.'; | 474 | *c1 = '.', *c2 = '.', *c3 = '.', *c4 = '.', *c5 = '.', *c6 = '.'; |
468 | 475 | ||
469 | if (class->usage_mask & LOCKF_USED_IN_HARDIRQ) | 476 | if (class->usage_mask & LOCKF_USED_IN_HARDIRQ) |
470 | *c1 = '+'; | 477 | *c1 = '+'; |
@@ -493,14 +500,29 @@ get_usage_chars(struct lock_class *class, char *c1, char *c2, char *c3, char *c4 | |||
493 | if (class->usage_mask & LOCKF_ENABLED_SOFTIRQS_READ) | 500 | if (class->usage_mask & LOCKF_ENABLED_SOFTIRQS_READ) |
494 | *c4 = '?'; | 501 | *c4 = '?'; |
495 | } | 502 | } |
503 | |||
504 | if (class->usage_mask & LOCKF_USED_IN_RECLAIM_FS) | ||
505 | *c5 = '+'; | ||
506 | else | ||
507 | if (class->usage_mask & LOCKF_HELD_OVER_RECLAIM_FS) | ||
508 | *c5 = '-'; | ||
509 | |||
510 | if (class->usage_mask & LOCKF_HELD_OVER_RECLAIM_FS_READ) | ||
511 | *c6 = '-'; | ||
512 | if (class->usage_mask & LOCKF_USED_IN_RECLAIM_FS_READ) { | ||
513 | *c6 = '+'; | ||
514 | if (class->usage_mask & LOCKF_HELD_OVER_RECLAIM_FS_READ) | ||
515 | *c6 = '?'; | ||
516 | } | ||
517 | |||
496 | } | 518 | } |
497 | 519 | ||
498 | static void print_lock_name(struct lock_class *class) | 520 | static void print_lock_name(struct lock_class *class) |
499 | { | 521 | { |
500 | char str[KSYM_NAME_LEN], c1, c2, c3, c4; | 522 | char str[KSYM_NAME_LEN], c1, c2, c3, c4, c5, c6; |
501 | const char *name; | 523 | const char *name; |
502 | 524 | ||
503 | get_usage_chars(class, &c1, &c2, &c3, &c4); | 525 | get_usage_chars(class, &c1, &c2, &c3, &c4, &c5, &c6); |
504 | 526 | ||
505 | name = class->name; | 527 | name = class->name; |
506 | if (!name) { | 528 | if (!name) { |
@@ -513,7 +535,7 @@ static void print_lock_name(struct lock_class *class) | |||
513 | if (class->subclass) | 535 | if (class->subclass) |
514 | printk("/%d", class->subclass); | 536 | printk("/%d", class->subclass); |
515 | } | 537 | } |
516 | printk("){%c%c%c%c}", c1, c2, c3, c4); | 538 | printk("){%c%c%c%c%c%c}", c1, c2, c3, c4, c5, c6); |
517 | } | 539 | } |
518 | 540 | ||
519 | static void print_lockdep_cache(struct lockdep_map *lock) | 541 | static void print_lockdep_cache(struct lockdep_map *lock) |
@@ -1306,6 +1328,26 @@ check_prev_add_irq(struct task_struct *curr, struct held_lock *prev, | |||
1306 | LOCK_ENABLED_SOFTIRQS, "soft")) | 1328 | LOCK_ENABLED_SOFTIRQS, "soft")) |
1307 | return 0; | 1329 | return 0; |
1308 | 1330 | ||
1331 | /* | ||
1332 | * Prove that the new dependency does not connect a reclaim-fs-safe | ||
1333 | * lock with a reclaim-fs-unsafe lock - to achieve this we search | ||
1334 | * the backwards-subgraph starting at <prev>, and the | ||
1335 | * forwards-subgraph starting at <next>: | ||
1336 | */ | ||
1337 | if (!check_usage(curr, prev, next, LOCK_USED_IN_RECLAIM_FS, | ||
1338 | LOCK_HELD_OVER_RECLAIM_FS, "reclaim-fs")) | ||
1339 | return 0; | ||
1340 | |||
1341 | /* | ||
1342 | * Prove that the new dependency does not connect a reclaim-fs-safe-read | ||
1343 | * lock with a reclaim-fs-unsafe lock - to achieve this we search | ||
1344 | * the backwards-subgraph starting at <prev>, and the | ||
1345 | * forwards-subgraph starting at <next>: | ||
1346 | */ | ||
1347 | if (!check_usage(curr, prev, next, LOCK_USED_IN_RECLAIM_FS_READ, | ||
1348 | LOCK_HELD_OVER_RECLAIM_FS, "reclaim-fs-read")) | ||
1349 | return 0; | ||
1350 | |||
1309 | return 1; | 1351 | return 1; |
1310 | } | 1352 | } |
1311 | 1353 | ||
@@ -1949,6 +1991,14 @@ static int softirq_verbose(struct lock_class *class) | |||
1949 | return 0; | 1991 | return 0; |
1950 | } | 1992 | } |
1951 | 1993 | ||
1994 | static int reclaim_verbose(struct lock_class *class) | ||
1995 | { | ||
1996 | #if RECLAIM_VERBOSE | ||
1997 | return class_filter(class); | ||
1998 | #endif | ||
1999 | return 0; | ||
2000 | } | ||
2001 | |||
1952 | #define STRICT_READ_CHECKS 1 | 2002 | #define STRICT_READ_CHECKS 1 |
1953 | 2003 | ||
1954 | static int mark_lock_irq(struct task_struct *curr, struct held_lock *this, | 2004 | static int mark_lock_irq(struct task_struct *curr, struct held_lock *this, |
@@ -2007,6 +2057,31 @@ static int mark_lock_irq(struct task_struct *curr, struct held_lock *this, | |||
2007 | if (softirq_verbose(hlock_class(this))) | 2057 | if (softirq_verbose(hlock_class(this))) |
2008 | ret = 2; | 2058 | ret = 2; |
2009 | break; | 2059 | break; |
2060 | case LOCK_USED_IN_RECLAIM_FS: | ||
2061 | if (!valid_state(curr, this, new_bit, LOCK_HELD_OVER_RECLAIM_FS)) | ||
2062 | return 0; | ||
2063 | if (!valid_state(curr, this, new_bit, | ||
2064 | LOCK_HELD_OVER_RECLAIM_FS_READ)) | ||
2065 | return 0; | ||
2066 | /* | ||
2067 | * just marked it reclaim-fs-safe, check that this lock | ||
2068 | * took no reclaim-fs-unsafe lock in the past: | ||
2069 | */ | ||
2070 | if (!check_usage_forwards(curr, this, | ||
2071 | LOCK_HELD_OVER_RECLAIM_FS, "reclaim-fs")) | ||
2072 | return 0; | ||
2073 | #if STRICT_READ_CHECKS | ||
2074 | /* | ||
2075 | * just marked it reclaim-fs-safe, check that this lock | ||
2076 | * took no reclaim-fs-unsafe-read lock in the past: | ||
2077 | */ | ||
2078 | if (!check_usage_forwards(curr, this, | ||
2079 | LOCK_HELD_OVER_RECLAIM_FS_READ, "reclaim-fs-read")) | ||
2080 | return 0; | ||
2081 | #endif | ||
2082 | if (reclaim_verbose(hlock_class(this))) | ||
2083 | ret = 2; | ||
2084 | break; | ||
2010 | case LOCK_USED_IN_HARDIRQ_READ: | 2085 | case LOCK_USED_IN_HARDIRQ_READ: |
2011 | if (!valid_state(curr, this, new_bit, LOCK_ENABLED_HARDIRQS)) | 2086 | if (!valid_state(curr, this, new_bit, LOCK_ENABLED_HARDIRQS)) |
2012 | return 0; | 2087 | return 0; |
@@ -2033,6 +2108,19 @@ static int mark_lock_irq(struct task_struct *curr, struct held_lock *this, | |||
2033 | if (softirq_verbose(hlock_class(this))) | 2108 | if (softirq_verbose(hlock_class(this))) |
2034 | ret = 2; | 2109 | ret = 2; |
2035 | break; | 2110 | break; |
2111 | case LOCK_USED_IN_RECLAIM_FS_READ: | ||
2112 | if (!valid_state(curr, this, new_bit, LOCK_HELD_OVER_RECLAIM_FS)) | ||
2113 | return 0; | ||
2114 | /* | ||
2115 | * just marked it reclaim-fs-read-safe, check that this lock | ||
2116 | * took no reclaim-fs-unsafe lock in the past: | ||
2117 | */ | ||
2118 | if (!check_usage_forwards(curr, this, | ||
2119 | LOCK_HELD_OVER_RECLAIM_FS, "reclaim-fs")) | ||
2120 | return 0; | ||
2121 | if (reclaim_verbose(hlock_class(this))) | ||
2122 | ret = 2; | ||
2123 | break; | ||
2036 | case LOCK_ENABLED_HARDIRQS: | 2124 | case LOCK_ENABLED_HARDIRQS: |
2037 | if (!valid_state(curr, this, new_bit, LOCK_USED_IN_HARDIRQ)) | 2125 | if (!valid_state(curr, this, new_bit, LOCK_USED_IN_HARDIRQ)) |
2038 | return 0; | 2126 | return 0; |
@@ -2085,6 +2173,32 @@ static int mark_lock_irq(struct task_struct *curr, struct held_lock *this, | |||
2085 | if (softirq_verbose(hlock_class(this))) | 2173 | if (softirq_verbose(hlock_class(this))) |
2086 | ret = 2; | 2174 | ret = 2; |
2087 | break; | 2175 | break; |
2176 | case LOCK_HELD_OVER_RECLAIM_FS: | ||
2177 | if (!valid_state(curr, this, new_bit, LOCK_USED_IN_RECLAIM_FS)) | ||
2178 | return 0; | ||
2179 | if (!valid_state(curr, this, new_bit, | ||
2180 | LOCK_USED_IN_RECLAIM_FS_READ)) | ||
2181 | return 0; | ||
2182 | /* | ||
2183 | * just marked it reclaim-fs-unsafe, check that no reclaim-fs-safe | ||
2184 | * lock in the system ever took it in the past: | ||
2185 | */ | ||
2186 | if (!check_usage_backwards(curr, this, | ||
2187 | LOCK_USED_IN_RECLAIM_FS, "reclaim-fs")) | ||
2188 | return 0; | ||
2189 | #if STRICT_READ_CHECKS | ||
2190 | /* | ||
2191 | * just marked it softirq-unsafe, check that no | ||
2192 | * softirq-safe-read lock in the system ever took | ||
2193 | * it in the past: | ||
2194 | */ | ||
2195 | if (!check_usage_backwards(curr, this, | ||
2196 | LOCK_USED_IN_RECLAIM_FS_READ, "reclaim-fs-read")) | ||
2197 | return 0; | ||
2198 | #endif | ||
2199 | if (reclaim_verbose(hlock_class(this))) | ||
2200 | ret = 2; | ||
2201 | break; | ||
2088 | case LOCK_ENABLED_HARDIRQS_READ: | 2202 | case LOCK_ENABLED_HARDIRQS_READ: |
2089 | if (!valid_state(curr, this, new_bit, LOCK_USED_IN_HARDIRQ)) | 2203 | if (!valid_state(curr, this, new_bit, LOCK_USED_IN_HARDIRQ)) |
2090 | return 0; | 2204 | return 0; |
@@ -2115,6 +2229,21 @@ static int mark_lock_irq(struct task_struct *curr, struct held_lock *this, | |||
2115 | if (softirq_verbose(hlock_class(this))) | 2229 | if (softirq_verbose(hlock_class(this))) |
2116 | ret = 2; | 2230 | ret = 2; |
2117 | break; | 2231 | break; |
2232 | case LOCK_HELD_OVER_RECLAIM_FS_READ: | ||
2233 | if (!valid_state(curr, this, new_bit, LOCK_USED_IN_RECLAIM_FS)) | ||
2234 | return 0; | ||
2235 | #if STRICT_READ_CHECKS | ||
2236 | /* | ||
2237 | * just marked it reclaim-fs-read-unsafe, check that no | ||
2238 | * reclaim-fs-safe lock in the system ever took it in the past: | ||
2239 | */ | ||
2240 | if (!check_usage_backwards(curr, this, | ||
2241 | LOCK_USED_IN_RECLAIM_FS, "reclaim-fs")) | ||
2242 | return 0; | ||
2243 | #endif | ||
2244 | if (reclaim_verbose(hlock_class(this))) | ||
2245 | ret = 2; | ||
2246 | break; | ||
2118 | default: | 2247 | default: |
2119 | WARN_ON(1); | 2248 | WARN_ON(1); |
2120 | break; | 2249 | break; |
@@ -2123,11 +2252,17 @@ static int mark_lock_irq(struct task_struct *curr, struct held_lock *this, | |||
2123 | return ret; | 2252 | return ret; |
2124 | } | 2253 | } |
2125 | 2254 | ||
2255 | enum mark_type { | ||
2256 | HARDIRQ, | ||
2257 | SOFTIRQ, | ||
2258 | RECLAIM_FS, | ||
2259 | }; | ||
2260 | |||
2126 | /* | 2261 | /* |
2127 | * Mark all held locks with a usage bit: | 2262 | * Mark all held locks with a usage bit: |
2128 | */ | 2263 | */ |
2129 | static int | 2264 | static int |
2130 | mark_held_locks(struct task_struct *curr, int hardirq) | 2265 | mark_held_locks(struct task_struct *curr, enum mark_type mark) |
2131 | { | 2266 | { |
2132 | enum lock_usage_bit usage_bit; | 2267 | enum lock_usage_bit usage_bit; |
2133 | struct held_lock *hlock; | 2268 | struct held_lock *hlock; |
@@ -2136,17 +2271,32 @@ mark_held_locks(struct task_struct *curr, int hardirq) | |||
2136 | for (i = 0; i < curr->lockdep_depth; i++) { | 2271 | for (i = 0; i < curr->lockdep_depth; i++) { |
2137 | hlock = curr->held_locks + i; | 2272 | hlock = curr->held_locks + i; |
2138 | 2273 | ||
2139 | if (hardirq) { | 2274 | switch (mark) { |
2275 | case HARDIRQ: | ||
2140 | if (hlock->read) | 2276 | if (hlock->read) |
2141 | usage_bit = LOCK_ENABLED_HARDIRQS_READ; | 2277 | usage_bit = LOCK_ENABLED_HARDIRQS_READ; |
2142 | else | 2278 | else |
2143 | usage_bit = LOCK_ENABLED_HARDIRQS; | 2279 | usage_bit = LOCK_ENABLED_HARDIRQS; |
2144 | } else { | 2280 | break; |
2281 | |||
2282 | case SOFTIRQ: | ||
2145 | if (hlock->read) | 2283 | if (hlock->read) |
2146 | usage_bit = LOCK_ENABLED_SOFTIRQS_READ; | 2284 | usage_bit = LOCK_ENABLED_SOFTIRQS_READ; |
2147 | else | 2285 | else |
2148 | usage_bit = LOCK_ENABLED_SOFTIRQS; | 2286 | usage_bit = LOCK_ENABLED_SOFTIRQS; |
2287 | break; | ||
2288 | |||
2289 | case RECLAIM_FS: | ||
2290 | if (hlock->read) | ||
2291 | usage_bit = LOCK_HELD_OVER_RECLAIM_FS_READ; | ||
2292 | else | ||
2293 | usage_bit = LOCK_HELD_OVER_RECLAIM_FS; | ||
2294 | break; | ||
2295 | |||
2296 | default: | ||
2297 | BUG(); | ||
2149 | } | 2298 | } |
2299 | |||
2150 | if (!mark_lock(curr, hlock, usage_bit)) | 2300 | if (!mark_lock(curr, hlock, usage_bit)) |
2151 | return 0; | 2301 | return 0; |
2152 | } | 2302 | } |
@@ -2200,7 +2350,7 @@ void trace_hardirqs_on_caller(unsigned long ip) | |||
2200 | * We are going to turn hardirqs on, so set the | 2350 | * We are going to turn hardirqs on, so set the |
2201 | * usage bit for all held locks: | 2351 | * usage bit for all held locks: |
2202 | */ | 2352 | */ |
2203 | if (!mark_held_locks(curr, 1)) | 2353 | if (!mark_held_locks(curr, HARDIRQ)) |
2204 | return; | 2354 | return; |
2205 | /* | 2355 | /* |
2206 | * If we have softirqs enabled, then set the usage | 2356 | * If we have softirqs enabled, then set the usage |
@@ -2208,7 +2358,7 @@ void trace_hardirqs_on_caller(unsigned long ip) | |||
2208 | * this bit from being set before) | 2358 | * this bit from being set before) |
2209 | */ | 2359 | */ |
2210 | if (curr->softirqs_enabled) | 2360 | if (curr->softirqs_enabled) |
2211 | if (!mark_held_locks(curr, 0)) | 2361 | if (!mark_held_locks(curr, SOFTIRQ)) |
2212 | return; | 2362 | return; |
2213 | 2363 | ||
2214 | curr->hardirq_enable_ip = ip; | 2364 | curr->hardirq_enable_ip = ip; |
@@ -2288,7 +2438,7 @@ void trace_softirqs_on(unsigned long ip) | |||
2288 | * enabled too: | 2438 | * enabled too: |
2289 | */ | 2439 | */ |
2290 | if (curr->hardirqs_enabled) | 2440 | if (curr->hardirqs_enabled) |
2291 | mark_held_locks(curr, 0); | 2441 | mark_held_locks(curr, SOFTIRQ); |
2292 | } | 2442 | } |
2293 | 2443 | ||
2294 | /* | 2444 | /* |
@@ -2317,6 +2467,31 @@ void trace_softirqs_off(unsigned long ip) | |||
2317 | debug_atomic_inc(&redundant_softirqs_off); | 2467 | debug_atomic_inc(&redundant_softirqs_off); |
2318 | } | 2468 | } |
2319 | 2469 | ||
2470 | void lockdep_trace_alloc(gfp_t gfp_mask) | ||
2471 | { | ||
2472 | struct task_struct *curr = current; | ||
2473 | |||
2474 | if (unlikely(!debug_locks)) | ||
2475 | return; | ||
2476 | |||
2477 | /* no reclaim without waiting on it */ | ||
2478 | if (!(gfp_mask & __GFP_WAIT)) | ||
2479 | return; | ||
2480 | |||
2481 | /* this guy won't enter reclaim */ | ||
2482 | if ((curr->flags & PF_MEMALLOC) && !(gfp_mask & __GFP_NOMEMALLOC)) | ||
2483 | return; | ||
2484 | |||
2485 | /* We're only interested __GFP_FS allocations for now */ | ||
2486 | if (!(gfp_mask & __GFP_FS)) | ||
2487 | return; | ||
2488 | |||
2489 | if (DEBUG_LOCKS_WARN_ON(irqs_disabled())) | ||
2490 | return; | ||
2491 | |||
2492 | mark_held_locks(curr, RECLAIM_FS); | ||
2493 | } | ||
2494 | |||
2320 | static int mark_irqflags(struct task_struct *curr, struct held_lock *hlock) | 2495 | static int mark_irqflags(struct task_struct *curr, struct held_lock *hlock) |
2321 | { | 2496 | { |
2322 | /* | 2497 | /* |
@@ -2362,6 +2537,22 @@ static int mark_irqflags(struct task_struct *curr, struct held_lock *hlock) | |||
2362 | } | 2537 | } |
2363 | } | 2538 | } |
2364 | 2539 | ||
2540 | /* | ||
2541 | * We reuse the irq context infrastructure more broadly as a general | ||
2542 | * context checking code. This tests GFP_FS recursion (a lock taken | ||
2543 | * during reclaim for a GFP_FS allocation is held over a GFP_FS | ||
2544 | * allocation). | ||
2545 | */ | ||
2546 | if (!hlock->trylock && (curr->lockdep_reclaim_gfp & __GFP_FS)) { | ||
2547 | if (hlock->read) { | ||
2548 | if (!mark_lock(curr, hlock, LOCK_USED_IN_RECLAIM_FS_READ)) | ||
2549 | return 0; | ||
2550 | } else { | ||
2551 | if (!mark_lock(curr, hlock, LOCK_USED_IN_RECLAIM_FS)) | ||
2552 | return 0; | ||
2553 | } | ||
2554 | } | ||
2555 | |||
2365 | return 1; | 2556 | return 1; |
2366 | } | 2557 | } |
2367 | 2558 | ||
@@ -2453,6 +2644,10 @@ static int mark_lock(struct task_struct *curr, struct held_lock *this, | |||
2453 | case LOCK_ENABLED_SOFTIRQS: | 2644 | case LOCK_ENABLED_SOFTIRQS: |
2454 | case LOCK_ENABLED_HARDIRQS_READ: | 2645 | case LOCK_ENABLED_HARDIRQS_READ: |
2455 | case LOCK_ENABLED_SOFTIRQS_READ: | 2646 | case LOCK_ENABLED_SOFTIRQS_READ: |
2647 | case LOCK_USED_IN_RECLAIM_FS: | ||
2648 | case LOCK_USED_IN_RECLAIM_FS_READ: | ||
2649 | case LOCK_HELD_OVER_RECLAIM_FS: | ||
2650 | case LOCK_HELD_OVER_RECLAIM_FS_READ: | ||
2456 | ret = mark_lock_irq(curr, this, new_bit); | 2651 | ret = mark_lock_irq(curr, this, new_bit); |
2457 | if (!ret) | 2652 | if (!ret) |
2458 | return 0; | 2653 | return 0; |
@@ -2966,6 +3161,16 @@ void lock_release(struct lockdep_map *lock, int nested, | |||
2966 | } | 3161 | } |
2967 | EXPORT_SYMBOL_GPL(lock_release); | 3162 | EXPORT_SYMBOL_GPL(lock_release); |
2968 | 3163 | ||
3164 | void lockdep_set_current_reclaim_state(gfp_t gfp_mask) | ||
3165 | { | ||
3166 | current->lockdep_reclaim_gfp = gfp_mask; | ||
3167 | } | ||
3168 | |||
3169 | void lockdep_clear_current_reclaim_state(void) | ||
3170 | { | ||
3171 | current->lockdep_reclaim_gfp = 0; | ||
3172 | } | ||
3173 | |||
2969 | #ifdef CONFIG_LOCK_STAT | 3174 | #ifdef CONFIG_LOCK_STAT |
2970 | static int | 3175 | static int |
2971 | print_lock_contention_bug(struct task_struct *curr, struct lockdep_map *lock, | 3176 | print_lock_contention_bug(struct task_struct *curr, struct lockdep_map *lock, |