diff options
Diffstat (limited to 'kernel/lockdep.c')
-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; |