diff options
author | Paul Moore <paul.moore@hp.com> | 2007-10-26 07:29:08 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2007-10-26 07:29:08 -0400 |
commit | 4be2700fb7b95f2a7cef9324879cafccab8774fc (patch) | |
tree | 8e3839c4e1c23c7d2b105f9ea45fb0891e3f0312 /net/netlabel | |
parent | 94d3b1e586f6d4c7150501bde284c544ce99073c (diff) |
[NetLabel]: correct usage of RCU locking
This fixes some awkward, and perhaps even problematic, RCU lock usage in the
NetLabel code as well as some other related trivial cleanups found when
looking through the RCU locking. Most of the changes involve removing the
redundant RCU read locks wrapping spinlocks in the case of a RCU writer.
Signed-off-by: Paul Moore <paul.moore@hp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/netlabel')
-rw-r--r-- | net/netlabel/netlabel_domainhash.c | 37 | ||||
-rw-r--r-- | net/netlabel/netlabel_mgmt.c | 4 | ||||
-rw-r--r-- | net/netlabel/netlabel_unlabeled.c | 4 |
3 files changed, 12 insertions, 33 deletions
diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c index b6c844b7e1c1..b3675bd7db33 100644 --- a/net/netlabel/netlabel_domainhash.c +++ b/net/netlabel/netlabel_domainhash.c | |||
@@ -178,11 +178,9 @@ int netlbl_domhsh_init(u32 size) | |||
178 | for (iter = 0; iter < hsh_tbl->size; iter++) | 178 | for (iter = 0; iter < hsh_tbl->size; iter++) |
179 | INIT_LIST_HEAD(&hsh_tbl->tbl[iter]); | 179 | INIT_LIST_HEAD(&hsh_tbl->tbl[iter]); |
180 | 180 | ||
181 | rcu_read_lock(); | ||
182 | spin_lock(&netlbl_domhsh_lock); | 181 | spin_lock(&netlbl_domhsh_lock); |
183 | rcu_assign_pointer(netlbl_domhsh, hsh_tbl); | 182 | rcu_assign_pointer(netlbl_domhsh, hsh_tbl); |
184 | spin_unlock(&netlbl_domhsh_lock); | 183 | spin_unlock(&netlbl_domhsh_lock); |
185 | rcu_read_unlock(); | ||
186 | 184 | ||
187 | return 0; | 185 | return 0; |
188 | } | 186 | } |
@@ -222,7 +220,6 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry, | |||
222 | entry->valid = 1; | 220 | entry->valid = 1; |
223 | INIT_RCU_HEAD(&entry->rcu); | 221 | INIT_RCU_HEAD(&entry->rcu); |
224 | 222 | ||
225 | ret_val = 0; | ||
226 | rcu_read_lock(); | 223 | rcu_read_lock(); |
227 | if (entry->domain != NULL) { | 224 | if (entry->domain != NULL) { |
228 | bkt = netlbl_domhsh_hash(entry->domain); | 225 | bkt = netlbl_domhsh_hash(entry->domain); |
@@ -233,7 +230,7 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry, | |||
233 | else | 230 | else |
234 | ret_val = -EEXIST; | 231 | ret_val = -EEXIST; |
235 | spin_unlock(&netlbl_domhsh_lock); | 232 | spin_unlock(&netlbl_domhsh_lock); |
236 | } else if (entry->domain == NULL) { | 233 | } else { |
237 | INIT_LIST_HEAD(&entry->list); | 234 | INIT_LIST_HEAD(&entry->list); |
238 | spin_lock(&netlbl_domhsh_def_lock); | 235 | spin_lock(&netlbl_domhsh_def_lock); |
239 | if (rcu_dereference(netlbl_domhsh_def) == NULL) | 236 | if (rcu_dereference(netlbl_domhsh_def) == NULL) |
@@ -241,9 +238,7 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry, | |||
241 | else | 238 | else |
242 | ret_val = -EEXIST; | 239 | ret_val = -EEXIST; |
243 | spin_unlock(&netlbl_domhsh_def_lock); | 240 | spin_unlock(&netlbl_domhsh_def_lock); |
244 | } else | 241 | } |
245 | ret_val = -EINVAL; | ||
246 | |||
247 | audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_ADD, audit_info); | 242 | audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_ADD, audit_info); |
248 | if (audit_buf != NULL) { | 243 | if (audit_buf != NULL) { |
249 | audit_log_format(audit_buf, | 244 | audit_log_format(audit_buf, |
@@ -262,7 +257,6 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry, | |||
262 | audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0); | 257 | audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0); |
263 | audit_log_end(audit_buf); | 258 | audit_log_end(audit_buf); |
264 | } | 259 | } |
265 | |||
266 | rcu_read_unlock(); | 260 | rcu_read_unlock(); |
267 | 261 | ||
268 | if (ret_val != 0) { | 262 | if (ret_val != 0) { |
@@ -313,38 +307,30 @@ int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info) | |||
313 | struct audit_buffer *audit_buf; | 307 | struct audit_buffer *audit_buf; |
314 | 308 | ||
315 | rcu_read_lock(); | 309 | rcu_read_lock(); |
316 | if (domain != NULL) | 310 | entry = netlbl_domhsh_search(domain, (domain != NULL ? 0 : 1)); |
317 | entry = netlbl_domhsh_search(domain, 0); | ||
318 | else | ||
319 | entry = netlbl_domhsh_search(domain, 1); | ||
320 | if (entry == NULL) | 311 | if (entry == NULL) |
321 | goto remove_return; | 312 | goto remove_return; |
322 | switch (entry->type) { | 313 | switch (entry->type) { |
323 | case NETLBL_NLTYPE_UNLABELED: | ||
324 | break; | ||
325 | case NETLBL_NLTYPE_CIPSOV4: | 314 | case NETLBL_NLTYPE_CIPSOV4: |
326 | ret_val = cipso_v4_doi_domhsh_remove(entry->type_def.cipsov4, | 315 | cipso_v4_doi_domhsh_remove(entry->type_def.cipsov4, |
327 | entry->domain); | 316 | entry->domain); |
328 | if (ret_val != 0) | ||
329 | goto remove_return; | ||
330 | break; | 317 | break; |
331 | } | 318 | } |
332 | ret_val = 0; | ||
333 | if (entry != rcu_dereference(netlbl_domhsh_def)) { | 319 | if (entry != rcu_dereference(netlbl_domhsh_def)) { |
334 | spin_lock(&netlbl_domhsh_lock); | 320 | spin_lock(&netlbl_domhsh_lock); |
335 | if (entry->valid) { | 321 | if (entry->valid) { |
336 | entry->valid = 0; | 322 | entry->valid = 0; |
337 | list_del_rcu(&entry->list); | 323 | list_del_rcu(&entry->list); |
338 | } else | 324 | ret_val = 0; |
339 | ret_val = -ENOENT; | 325 | } |
340 | spin_unlock(&netlbl_domhsh_lock); | 326 | spin_unlock(&netlbl_domhsh_lock); |
341 | } else { | 327 | } else { |
342 | spin_lock(&netlbl_domhsh_def_lock); | 328 | spin_lock(&netlbl_domhsh_def_lock); |
343 | if (entry->valid) { | 329 | if (entry->valid) { |
344 | entry->valid = 0; | 330 | entry->valid = 0; |
345 | rcu_assign_pointer(netlbl_domhsh_def, NULL); | 331 | rcu_assign_pointer(netlbl_domhsh_def, NULL); |
346 | } else | 332 | ret_val = 0; |
347 | ret_val = -ENOENT; | 333 | } |
348 | spin_unlock(&netlbl_domhsh_def_lock); | 334 | spin_unlock(&netlbl_domhsh_def_lock); |
349 | } | 335 | } |
350 | 336 | ||
@@ -357,11 +343,10 @@ int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info) | |||
357 | audit_log_end(audit_buf); | 343 | audit_log_end(audit_buf); |
358 | } | 344 | } |
359 | 345 | ||
360 | if (ret_val == 0) | ||
361 | call_rcu(&entry->rcu, netlbl_domhsh_free_entry); | ||
362 | |||
363 | remove_return: | 346 | remove_return: |
364 | rcu_read_unlock(); | 347 | rcu_read_unlock(); |
348 | if (ret_val == 0) | ||
349 | call_rcu(&entry->rcu, netlbl_domhsh_free_entry); | ||
365 | return ret_val; | 350 | return ret_val; |
366 | } | 351 | } |
367 | 352 | ||
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c index 5315dacc5222..56483377997a 100644 --- a/net/netlabel/netlabel_mgmt.c +++ b/net/netlabel/netlabel_mgmt.c | |||
@@ -85,11 +85,9 @@ static const struct nla_policy netlbl_mgmt_genl_policy[NLBL_MGMT_A_MAX + 1] = { | |||
85 | */ | 85 | */ |
86 | void netlbl_mgmt_protocount_inc(void) | 86 | void netlbl_mgmt_protocount_inc(void) |
87 | { | 87 | { |
88 | rcu_read_lock(); | ||
89 | spin_lock(&netlabel_mgmt_protocount_lock); | 88 | spin_lock(&netlabel_mgmt_protocount_lock); |
90 | netlabel_mgmt_protocount++; | 89 | netlabel_mgmt_protocount++; |
91 | spin_unlock(&netlabel_mgmt_protocount_lock); | 90 | spin_unlock(&netlabel_mgmt_protocount_lock); |
92 | rcu_read_unlock(); | ||
93 | } | 91 | } |
94 | 92 | ||
95 | /** | 93 | /** |
@@ -103,12 +101,10 @@ void netlbl_mgmt_protocount_inc(void) | |||
103 | */ | 101 | */ |
104 | void netlbl_mgmt_protocount_dec(void) | 102 | void netlbl_mgmt_protocount_dec(void) |
105 | { | 103 | { |
106 | rcu_read_lock(); | ||
107 | spin_lock(&netlabel_mgmt_protocount_lock); | 104 | spin_lock(&netlabel_mgmt_protocount_lock); |
108 | if (netlabel_mgmt_protocount > 0) | 105 | if (netlabel_mgmt_protocount > 0) |
109 | netlabel_mgmt_protocount--; | 106 | netlabel_mgmt_protocount--; |
110 | spin_unlock(&netlabel_mgmt_protocount_lock); | 107 | spin_unlock(&netlabel_mgmt_protocount_lock); |
111 | rcu_read_unlock(); | ||
112 | } | 108 | } |
113 | 109 | ||
114 | /** | 110 | /** |
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 5c303c68af1d..348292450deb 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c | |||
@@ -84,12 +84,10 @@ static void netlbl_unlabel_acceptflg_set(u8 value, | |||
84 | struct audit_buffer *audit_buf; | 84 | struct audit_buffer *audit_buf; |
85 | u8 old_val; | 85 | u8 old_val; |
86 | 86 | ||
87 | rcu_read_lock(); | ||
88 | old_val = netlabel_unlabel_acceptflg; | ||
89 | spin_lock(&netlabel_unlabel_acceptflg_lock); | 87 | spin_lock(&netlabel_unlabel_acceptflg_lock); |
88 | old_val = netlabel_unlabel_acceptflg; | ||
90 | netlabel_unlabel_acceptflg = value; | 89 | netlabel_unlabel_acceptflg = value; |
91 | spin_unlock(&netlabel_unlabel_acceptflg_lock); | 90 | spin_unlock(&netlabel_unlabel_acceptflg_lock); |
92 | rcu_read_unlock(); | ||
93 | 91 | ||
94 | audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_ALLOW, | 92 | audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_ALLOW, |
95 | audit_info); | 93 | audit_info); |