diff options
-rw-r--r-- | kernel/lockdep.c | 58 |
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 | ||
2060 | typedef int (*check_usage_f)(struct task_struct *, struct held_lock *, | ||
2061 | enum lock_usage_bit bit, const char *name); | ||
2062 | |||
2060 | static int | 2063 | static int |
2061 | mark_lock_irq_used_in(struct task_struct *curr, struct held_lock *this, | 2064 | mark_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 | ||
2128 | static int | ||
2129 | mark_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 | |||
2162 | static int mark_lock_irq(struct task_struct *curr, struct held_lock *this, | 2136 | static 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; |