diff options
| -rw-r--r-- | kernel/lockdep.c | 37 |
1 files changed, 30 insertions, 7 deletions
diff --git a/kernel/lockdep.c b/kernel/lockdep.c index f40d916c191c..02e6e066d563 100644 --- a/kernel/lockdep.c +++ b/kernel/lockdep.c | |||
| @@ -2054,6 +2054,9 @@ static int exclusive_bit(int new_bit) | |||
| 2054 | int state = new_bit & ~3; | 2054 | int state = new_bit & ~3; |
| 2055 | int dir = new_bit & 2; | 2055 | int dir = new_bit & 2; |
| 2056 | 2056 | ||
| 2057 | /* | ||
| 2058 | * keep state, bit flip the direction and strip read. | ||
| 2059 | */ | ||
| 2057 | return state | (dir ^ 2); | 2060 | return state | (dir ^ 2); |
| 2058 | } | 2061 | } |
| 2059 | 2062 | ||
| @@ -2070,22 +2073,42 @@ mark_lock_irq(struct task_struct *curr, struct held_lock *this, int new_bit) | |||
| 2070 | int read = new_bit & 1; | 2073 | int read = new_bit & 1; |
| 2071 | int dir = new_bit & 2; | 2074 | int dir = new_bit & 2; |
| 2072 | 2075 | ||
| 2076 | /* | ||
| 2077 | * mark USED_IN has to look forwards -- to ensure no dependency | ||
| 2078 | * has ENABLED state, which would allow recursion deadlocks. | ||
| 2079 | * | ||
| 2080 | * mark ENABLED has to look backwards -- to ensure no dependee | ||
| 2081 | * has USED_IN state, which, again, would allow recursion deadlocks. | ||
| 2082 | */ | ||
| 2073 | check_usage_f usage = dir ? | 2083 | check_usage_f usage = dir ? |
| 2074 | check_usage_backwards : check_usage_forwards; | 2084 | check_usage_backwards : check_usage_forwards; |
| 2075 | 2085 | ||
| 2086 | /* | ||
| 2087 | * Validate that this particular lock does not have conflicting | ||
| 2088 | * usage states. | ||
| 2089 | */ | ||
| 2076 | if (!valid_state(curr, this, new_bit, excl_bit)) | 2090 | if (!valid_state(curr, this, new_bit, excl_bit)) |
| 2077 | return 0; | 2091 | return 0; |
| 2078 | 2092 | ||
| 2079 | if (!read && !valid_state(curr, this, new_bit, excl_bit + 1)) | 2093 | /* |
| 2080 | return 0; | 2094 | * Validate that the lock dependencies don't have conflicting usage |
| 2081 | 2095 | * states. | |
| 2082 | if ((!read || (!dir || STRICT_READ_CHECKS)) && | 2096 | */ |
| 2097 | if ((!read || !dir || STRICT_READ_CHECKS) && | ||
| 2083 | !usage(curr, this, excl_bit, name)) | 2098 | !usage(curr, this, excl_bit, name)) |
| 2084 | return 0; | 2099 | return 0; |
| 2085 | 2100 | ||
| 2086 | if ((!read && STRICT_READ_CHECKS) && | 2101 | /* |
| 2087 | !usage(curr, this, excl_bit + 1, rname)) | 2102 | * Check for read in write conflicts |
| 2088 | return 0; | 2103 | */ |
| 2104 | if (!read) { | ||
| 2105 | if (!valid_state(curr, this, new_bit, excl_bit + 1)) | ||
| 2106 | return 0; | ||
| 2107 | |||
| 2108 | if (STRICT_READ_CHECKS && | ||
| 2109 | !usage(curr, this, excl_bit + 1, rname)) | ||
| 2110 | return 0; | ||
| 2111 | } | ||
| 2089 | 2112 | ||
| 2090 | if (state_verbose(new_bit, hlock_class(this))) | 2113 | if (state_verbose(new_bit, hlock_class(this))) |
| 2091 | return 2; | 2114 | return 2; |
