aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/lockdep.c37
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;