aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/lockdep.c58
1 files changed, 15 insertions, 43 deletions
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index 2d95f9db2598..1ba52e68355a 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -2057,31 +2057,39 @@ static int exclusive_bit(int new_bit)
2057 return state | (dir ^ 2); 2057 return state | (dir ^ 2);
2058} 2058}
2059 2059
2060typedef int (*check_usage_f)(struct task_struct *, struct held_lock *,
2061 enum lock_usage_bit bit, const char *name);
2062
2060static int 2063static int
2061mark_lock_irq_used_in(struct task_struct *curr, struct held_lock *this, 2064mark_lock_irq_write(struct task_struct *curr, struct held_lock *this,
2062 int new_bit) 2065 int new_bit)
2063{ 2066{
2064 const char *name = state_name(new_bit); 2067 const char *name = state_name(new_bit);
2065 const char *rname = state_rname(new_bit); 2068 const char *rname = state_rname(new_bit);
2066 2069
2067 int excl_bit = exclusive_bit(new_bit); 2070 int excl_bit = exclusive_bit(new_bit);
2071 int dir = new_bit & 2;
2072
2073 check_usage_f usage = dir ?
2074 check_usage_backwards : check_usage_forwards;
2068 2075
2069 if (!valid_state(curr, this, new_bit, excl_bit)) 2076 if (!valid_state(curr, this, new_bit, excl_bit))
2070 return 0; 2077 return 0;
2071 if (!valid_state(curr, this, new_bit, excl_bit + 1)) 2078 if (!valid_state(curr, this, new_bit, excl_bit + 1))
2072 return 0; 2079 return 0;
2080
2073 /* 2081 /*
2074 * just marked it hardirq-safe, check that this lock 2082 * just marked it hardirq-safe, check that this lock
2075 * took no hardirq-unsafe lock in the past: 2083 * took no hardirq-unsafe lock in the past:
2076 */ 2084 */
2077 if (!check_usage_forwards(curr, this, excl_bit, name)) 2085 if (!usage(curr, this, excl_bit, name))
2078 return 0; 2086 return 0;
2079#if STRICT_READ_CHECKS 2087#if STRICT_READ_CHECKS
2080 /* 2088 /*
2081 * just marked it hardirq-safe, check that this lock 2089 * just marked it hardirq-safe, check that this lock
2082 * took no hardirq-unsafe-read lock in the past: 2090 * took no hardirq-unsafe-read lock in the past:
2083 */ 2091 */
2084 if (!check_usage_forwards(curr, this, excl_bit + 1, rname)) 2092 if (!usage(curr, this, excl_bit + 1, rname))
2085 return 0; 2093 return 0;
2086#endif 2094#endif
2087 if (state_verbose(new_bit, hlock_class(this))) 2095 if (state_verbose(new_bit, hlock_class(this)))
@@ -2125,40 +2133,6 @@ mark_lock_irq_read(struct task_struct *curr, struct held_lock *this,
2125 return 1; 2133 return 1;
2126} 2134}
2127 2135
2128static int
2129mark_lock_irq_enabled(struct task_struct *curr, struct held_lock *this,
2130 int new_bit)
2131{
2132 const char *name = state_name(new_bit);
2133 const char *rname = state_rname(new_bit);
2134
2135 int excl_bit = exclusive_bit(new_bit);
2136
2137 if (!valid_state(curr, this, new_bit, excl_bit))
2138 return 0;
2139 if (!valid_state(curr, this, new_bit, excl_bit + 1))
2140 return 0;
2141 /*
2142 * just marked it hardirq-unsafe, check that no hardirq-safe
2143 * lock in the system ever took it in the past:
2144 */
2145 if (!check_usage_backwards(curr, this, excl_bit, name))
2146 return 0;
2147#if STRICT_READ_CHECKS
2148 /*
2149 * just marked it hardirq-unsafe, check that no
2150 * hardirq-safe-read lock in the system ever took
2151 * it in the past:
2152 */
2153 if (!check_usage_backwards(curr, this, excl_bit + 1, rname))
2154 return 0;
2155#endif
2156 if (state_verbose(new_bit, hlock_class(this)))
2157 return 2;
2158
2159 return 1;
2160}
2161
2162static int mark_lock_irq(struct task_struct *curr, struct held_lock *this, 2136static int mark_lock_irq(struct task_struct *curr, struct held_lock *this,
2163 enum lock_usage_bit new_bit) 2137 enum lock_usage_bit new_bit)
2164{ 2138{
@@ -2168,7 +2142,10 @@ static int mark_lock_irq(struct task_struct *curr, struct held_lock *this,
2168 case LOCK_USED_IN_HARDIRQ: 2142 case LOCK_USED_IN_HARDIRQ:
2169 case LOCK_USED_IN_SOFTIRQ: 2143 case LOCK_USED_IN_SOFTIRQ:
2170 case LOCK_USED_IN_RECLAIM_FS: 2144 case LOCK_USED_IN_RECLAIM_FS:
2171 return mark_lock_irq_used_in(curr, this, new_bit); 2145 case LOCK_ENABLED_HARDIRQ:
2146 case LOCK_ENABLED_SOFTIRQ:
2147 case LOCK_ENABLED_RECLAIM_FS:
2148 return mark_lock_irq_write(curr, this, new_bit);
2172 2149
2173 case LOCK_USED_IN_HARDIRQ_READ: 2150 case LOCK_USED_IN_HARDIRQ_READ:
2174 case LOCK_USED_IN_SOFTIRQ_READ: 2151 case LOCK_USED_IN_SOFTIRQ_READ:
@@ -2178,11 +2155,6 @@ static int mark_lock_irq(struct task_struct *curr, struct held_lock *this,
2178 case LOCK_ENABLED_RECLAIM_FS_READ: 2155 case LOCK_ENABLED_RECLAIM_FS_READ:
2179 return mark_lock_irq_read(curr, this, new_bit); 2156 return mark_lock_irq_read(curr, this, new_bit);
2180 2157
2181 case LOCK_ENABLED_HARDIRQ:
2182 case LOCK_ENABLED_SOFTIRQ:
2183 case LOCK_ENABLED_RECLAIM_FS:
2184 return mark_lock_irq_enabled(curr, this, new_bit);
2185
2186 default: 2158 default:
2187 WARN_ON(1); 2159 WARN_ON(1);
2188 break; 2160 break;