aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Moore <paul.moore@hp.com>2007-10-26 07:29:08 -0400
committerDavid S. Miller <davem@davemloft.net>2007-10-26 07:29:08 -0400
commit4be2700fb7b95f2a7cef9324879cafccab8774fc (patch)
tree8e3839c4e1c23c7d2b105f9ea45fb0891e3f0312
parent94d3b1e586f6d4c7150501bde284c544ce99073c (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>
-rw-r--r--net/ipv4/cipso_ipv4.c39
-rw-r--r--net/netlabel/netlabel_domainhash.c37
-rw-r--r--net/netlabel/netlabel_mgmt.c4
-rw-r--r--net/netlabel/netlabel_unlabeled.c4
4 files changed, 22 insertions, 62 deletions
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index 805a78e6ed55..f18e88bc86ec 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -504,22 +504,16 @@ int cipso_v4_doi_add(struct cipso_v4_doi *doi_def)
504 INIT_RCU_HEAD(&doi_def->rcu); 504 INIT_RCU_HEAD(&doi_def->rcu);
505 INIT_LIST_HEAD(&doi_def->dom_list); 505 INIT_LIST_HEAD(&doi_def->dom_list);
506 506
507 rcu_read_lock();
508 if (cipso_v4_doi_search(doi_def->doi) != NULL)
509 goto doi_add_failure_rlock;
510 spin_lock(&cipso_v4_doi_list_lock); 507 spin_lock(&cipso_v4_doi_list_lock);
511 if (cipso_v4_doi_search(doi_def->doi) != NULL) 508 if (cipso_v4_doi_search(doi_def->doi) != NULL)
512 goto doi_add_failure_slock; 509 goto doi_add_failure;
513 list_add_tail_rcu(&doi_def->list, &cipso_v4_doi_list); 510 list_add_tail_rcu(&doi_def->list, &cipso_v4_doi_list);
514 spin_unlock(&cipso_v4_doi_list_lock); 511 spin_unlock(&cipso_v4_doi_list_lock);
515 rcu_read_unlock();
516 512
517 return 0; 513 return 0;
518 514
519doi_add_failure_slock: 515doi_add_failure:
520 spin_unlock(&cipso_v4_doi_list_lock); 516 spin_unlock(&cipso_v4_doi_list_lock);
521doi_add_failure_rlock:
522 rcu_read_unlock();
523 return -EEXIST; 517 return -EEXIST;
524} 518}
525 519
@@ -543,29 +537,23 @@ int cipso_v4_doi_remove(u32 doi,
543 struct cipso_v4_doi *doi_def; 537 struct cipso_v4_doi *doi_def;
544 struct cipso_v4_domhsh_entry *dom_iter; 538 struct cipso_v4_domhsh_entry *dom_iter;
545 539
546 rcu_read_lock(); 540 spin_lock(&cipso_v4_doi_list_lock);
547 if (cipso_v4_doi_search(doi) != NULL) { 541 doi_def = cipso_v4_doi_search(doi);
548 spin_lock(&cipso_v4_doi_list_lock); 542 if (doi_def != NULL) {
549 doi_def = cipso_v4_doi_search(doi);
550 if (doi_def == NULL) {
551 spin_unlock(&cipso_v4_doi_list_lock);
552 rcu_read_unlock();
553 return -ENOENT;
554 }
555 doi_def->valid = 0; 543 doi_def->valid = 0;
556 list_del_rcu(&doi_def->list); 544 list_del_rcu(&doi_def->list);
557 spin_unlock(&cipso_v4_doi_list_lock); 545 spin_unlock(&cipso_v4_doi_list_lock);
546 rcu_read_lock();
558 list_for_each_entry_rcu(dom_iter, &doi_def->dom_list, list) 547 list_for_each_entry_rcu(dom_iter, &doi_def->dom_list, list)
559 if (dom_iter->valid) 548 if (dom_iter->valid)
560 netlbl_domhsh_remove(dom_iter->domain, 549 netlbl_domhsh_remove(dom_iter->domain,
561 audit_info); 550 audit_info);
562 cipso_v4_cache_invalidate();
563 rcu_read_unlock(); 551 rcu_read_unlock();
564 552 cipso_v4_cache_invalidate();
565 call_rcu(&doi_def->rcu, callback); 553 call_rcu(&doi_def->rcu, callback);
566 return 0; 554 return 0;
567 } 555 }
568 rcu_read_unlock(); 556 spin_unlock(&cipso_v4_doi_list_lock);
569 557
570 return -ENOENT; 558 return -ENOENT;
571} 559}
@@ -653,22 +641,19 @@ int cipso_v4_doi_domhsh_add(struct cipso_v4_doi *doi_def, const char *domain)
653 new_dom->valid = 1; 641 new_dom->valid = 1;
654 INIT_RCU_HEAD(&new_dom->rcu); 642 INIT_RCU_HEAD(&new_dom->rcu);
655 643
656 rcu_read_lock();
657 spin_lock(&cipso_v4_doi_list_lock); 644 spin_lock(&cipso_v4_doi_list_lock);
658 list_for_each_entry_rcu(iter, &doi_def->dom_list, list) 645 list_for_each_entry(iter, &doi_def->dom_list, list)
659 if (iter->valid && 646 if (iter->valid &&
660 ((domain != NULL && iter->domain != NULL && 647 ((domain != NULL && iter->domain != NULL &&
661 strcmp(iter->domain, domain) == 0) || 648 strcmp(iter->domain, domain) == 0) ||
662 (domain == NULL && iter->domain == NULL))) { 649 (domain == NULL && iter->domain == NULL))) {
663 spin_unlock(&cipso_v4_doi_list_lock); 650 spin_unlock(&cipso_v4_doi_list_lock);
664 rcu_read_unlock();
665 kfree(new_dom->domain); 651 kfree(new_dom->domain);
666 kfree(new_dom); 652 kfree(new_dom);
667 return -EEXIST; 653 return -EEXIST;
668 } 654 }
669 list_add_tail_rcu(&new_dom->list, &doi_def->dom_list); 655 list_add_tail_rcu(&new_dom->list, &doi_def->dom_list);
670 spin_unlock(&cipso_v4_doi_list_lock); 656 spin_unlock(&cipso_v4_doi_list_lock);
671 rcu_read_unlock();
672 657
673 return 0; 658 return 0;
674} 659}
@@ -689,9 +674,8 @@ int cipso_v4_doi_domhsh_remove(struct cipso_v4_doi *doi_def,
689{ 674{
690 struct cipso_v4_domhsh_entry *iter; 675 struct cipso_v4_domhsh_entry *iter;
691 676
692 rcu_read_lock();
693 spin_lock(&cipso_v4_doi_list_lock); 677 spin_lock(&cipso_v4_doi_list_lock);
694 list_for_each_entry_rcu(iter, &doi_def->dom_list, list) 678 list_for_each_entry(iter, &doi_def->dom_list, list)
695 if (iter->valid && 679 if (iter->valid &&
696 ((domain != NULL && iter->domain != NULL && 680 ((domain != NULL && iter->domain != NULL &&
697 strcmp(iter->domain, domain) == 0) || 681 strcmp(iter->domain, domain) == 0) ||
@@ -699,13 +683,10 @@ int cipso_v4_doi_domhsh_remove(struct cipso_v4_doi *doi_def,
699 iter->valid = 0; 683 iter->valid = 0;
700 list_del_rcu(&iter->list); 684 list_del_rcu(&iter->list);
701 spin_unlock(&cipso_v4_doi_list_lock); 685 spin_unlock(&cipso_v4_doi_list_lock);
702 rcu_read_unlock();
703 call_rcu(&iter->rcu, cipso_v4_doi_domhsh_free); 686 call_rcu(&iter->rcu, cipso_v4_doi_domhsh_free);
704
705 return 0; 687 return 0;
706 } 688 }
707 spin_unlock(&cipso_v4_doi_list_lock); 689 spin_unlock(&cipso_v4_doi_list_lock);
708 rcu_read_unlock();
709 690
710 return -ENOENT; 691 return -ENOENT;
711} 692}
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
363remove_return: 346remove_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 */
86void netlbl_mgmt_protocount_inc(void) 86void 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 */
104void netlbl_mgmt_protocount_dec(void) 102void 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);