Skip to content

Commit

Permalink
[NetLabel]: correct usage of RCU locking
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Paul Moore authored and David S. Miller committed Oct 26, 2007
1 parent 94d3b1e commit 4be2700
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 62 deletions.
39 changes: 10 additions & 29 deletions net/ipv4/cipso_ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -504,22 +504,16 @@ int cipso_v4_doi_add(struct cipso_v4_doi *doi_def)
INIT_RCU_HEAD(&doi_def->rcu);
INIT_LIST_HEAD(&doi_def->dom_list);

rcu_read_lock();
if (cipso_v4_doi_search(doi_def->doi) != NULL)
goto doi_add_failure_rlock;
spin_lock(&cipso_v4_doi_list_lock);
if (cipso_v4_doi_search(doi_def->doi) != NULL)
goto doi_add_failure_slock;
goto doi_add_failure;
list_add_tail_rcu(&doi_def->list, &cipso_v4_doi_list);
spin_unlock(&cipso_v4_doi_list_lock);
rcu_read_unlock();

return 0;

doi_add_failure_slock:
doi_add_failure:
spin_unlock(&cipso_v4_doi_list_lock);
doi_add_failure_rlock:
rcu_read_unlock();
return -EEXIST;
}

Expand All @@ -543,29 +537,23 @@ int cipso_v4_doi_remove(u32 doi,
struct cipso_v4_doi *doi_def;
struct cipso_v4_domhsh_entry *dom_iter;

rcu_read_lock();
if (cipso_v4_doi_search(doi) != NULL) {
spin_lock(&cipso_v4_doi_list_lock);
doi_def = cipso_v4_doi_search(doi);
if (doi_def == NULL) {
spin_unlock(&cipso_v4_doi_list_lock);
rcu_read_unlock();
return -ENOENT;
}
spin_lock(&cipso_v4_doi_list_lock);
doi_def = cipso_v4_doi_search(doi);
if (doi_def != NULL) {
doi_def->valid = 0;
list_del_rcu(&doi_def->list);
spin_unlock(&cipso_v4_doi_list_lock);
rcu_read_lock();
list_for_each_entry_rcu(dom_iter, &doi_def->dom_list, list)
if (dom_iter->valid)
netlbl_domhsh_remove(dom_iter->domain,
audit_info);
cipso_v4_cache_invalidate();
rcu_read_unlock();

cipso_v4_cache_invalidate();
call_rcu(&doi_def->rcu, callback);
return 0;
}
rcu_read_unlock();
spin_unlock(&cipso_v4_doi_list_lock);

return -ENOENT;
}
Expand Down Expand Up @@ -653,22 +641,19 @@ int cipso_v4_doi_domhsh_add(struct cipso_v4_doi *doi_def, const char *domain)
new_dom->valid = 1;
INIT_RCU_HEAD(&new_dom->rcu);

rcu_read_lock();
spin_lock(&cipso_v4_doi_list_lock);
list_for_each_entry_rcu(iter, &doi_def->dom_list, list)
list_for_each_entry(iter, &doi_def->dom_list, list)
if (iter->valid &&
((domain != NULL && iter->domain != NULL &&
strcmp(iter->domain, domain) == 0) ||
(domain == NULL && iter->domain == NULL))) {
spin_unlock(&cipso_v4_doi_list_lock);
rcu_read_unlock();
kfree(new_dom->domain);
kfree(new_dom);
return -EEXIST;
}
list_add_tail_rcu(&new_dom->list, &doi_def->dom_list);
spin_unlock(&cipso_v4_doi_list_lock);
rcu_read_unlock();

return 0;
}
Expand All @@ -689,23 +674,19 @@ int cipso_v4_doi_domhsh_remove(struct cipso_v4_doi *doi_def,
{
struct cipso_v4_domhsh_entry *iter;

rcu_read_lock();
spin_lock(&cipso_v4_doi_list_lock);
list_for_each_entry_rcu(iter, &doi_def->dom_list, list)
list_for_each_entry(iter, &doi_def->dom_list, list)
if (iter->valid &&
((domain != NULL && iter->domain != NULL &&
strcmp(iter->domain, domain) == 0) ||
(domain == NULL && iter->domain == NULL))) {
iter->valid = 0;
list_del_rcu(&iter->list);
spin_unlock(&cipso_v4_doi_list_lock);
rcu_read_unlock();
call_rcu(&iter->rcu, cipso_v4_doi_domhsh_free);

return 0;
}
spin_unlock(&cipso_v4_doi_list_lock);
rcu_read_unlock();

return -ENOENT;
}
Expand Down
37 changes: 11 additions & 26 deletions net/netlabel/netlabel_domainhash.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,11 +178,9 @@ int netlbl_domhsh_init(u32 size)
for (iter = 0; iter < hsh_tbl->size; iter++)
INIT_LIST_HEAD(&hsh_tbl->tbl[iter]);

rcu_read_lock();
spin_lock(&netlbl_domhsh_lock);
rcu_assign_pointer(netlbl_domhsh, hsh_tbl);
spin_unlock(&netlbl_domhsh_lock);
rcu_read_unlock();

return 0;
}
Expand Down Expand Up @@ -222,7 +220,6 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
entry->valid = 1;
INIT_RCU_HEAD(&entry->rcu);

ret_val = 0;
rcu_read_lock();
if (entry->domain != NULL) {
bkt = netlbl_domhsh_hash(entry->domain);
Expand All @@ -233,17 +230,15 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
else
ret_val = -EEXIST;
spin_unlock(&netlbl_domhsh_lock);
} else if (entry->domain == NULL) {
} else {
INIT_LIST_HEAD(&entry->list);
spin_lock(&netlbl_domhsh_def_lock);
if (rcu_dereference(netlbl_domhsh_def) == NULL)
rcu_assign_pointer(netlbl_domhsh_def, entry);
else
ret_val = -EEXIST;
spin_unlock(&netlbl_domhsh_def_lock);
} else
ret_val = -EINVAL;

}
audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_ADD, audit_info);
if (audit_buf != NULL) {
audit_log_format(audit_buf,
Expand All @@ -262,7 +257,6 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0);
audit_log_end(audit_buf);
}

rcu_read_unlock();

if (ret_val != 0) {
Expand Down Expand Up @@ -313,38 +307,30 @@ int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info)
struct audit_buffer *audit_buf;

rcu_read_lock();
if (domain != NULL)
entry = netlbl_domhsh_search(domain, 0);
else
entry = netlbl_domhsh_search(domain, 1);
entry = netlbl_domhsh_search(domain, (domain != NULL ? 0 : 1));
if (entry == NULL)
goto remove_return;
switch (entry->type) {
case NETLBL_NLTYPE_UNLABELED:
break;
case NETLBL_NLTYPE_CIPSOV4:
ret_val = cipso_v4_doi_domhsh_remove(entry->type_def.cipsov4,
entry->domain);
if (ret_val != 0)
goto remove_return;
cipso_v4_doi_domhsh_remove(entry->type_def.cipsov4,
entry->domain);
break;
}
ret_val = 0;
if (entry != rcu_dereference(netlbl_domhsh_def)) {
spin_lock(&netlbl_domhsh_lock);
if (entry->valid) {
entry->valid = 0;
list_del_rcu(&entry->list);
} else
ret_val = -ENOENT;
ret_val = 0;
}
spin_unlock(&netlbl_domhsh_lock);
} else {
spin_lock(&netlbl_domhsh_def_lock);
if (entry->valid) {
entry->valid = 0;
rcu_assign_pointer(netlbl_domhsh_def, NULL);
} else
ret_val = -ENOENT;
ret_val = 0;
}
spin_unlock(&netlbl_domhsh_def_lock);
}

Expand All @@ -357,11 +343,10 @@ int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info)
audit_log_end(audit_buf);
}

if (ret_val == 0)
call_rcu(&entry->rcu, netlbl_domhsh_free_entry);

remove_return:
rcu_read_unlock();
if (ret_val == 0)
call_rcu(&entry->rcu, netlbl_domhsh_free_entry);
return ret_val;
}

Expand Down
4 changes: 0 additions & 4 deletions net/netlabel/netlabel_mgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,9 @@ static const struct nla_policy netlbl_mgmt_genl_policy[NLBL_MGMT_A_MAX + 1] = {
*/
void netlbl_mgmt_protocount_inc(void)
{
rcu_read_lock();
spin_lock(&netlabel_mgmt_protocount_lock);
netlabel_mgmt_protocount++;
spin_unlock(&netlabel_mgmt_protocount_lock);
rcu_read_unlock();
}

/**
Expand All @@ -103,12 +101,10 @@ void netlbl_mgmt_protocount_inc(void)
*/
void netlbl_mgmt_protocount_dec(void)
{
rcu_read_lock();
spin_lock(&netlabel_mgmt_protocount_lock);
if (netlabel_mgmt_protocount > 0)
netlabel_mgmt_protocount--;
spin_unlock(&netlabel_mgmt_protocount_lock);
rcu_read_unlock();
}

/**
Expand Down
4 changes: 1 addition & 3 deletions net/netlabel/netlabel_unlabeled.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,10 @@ static void netlbl_unlabel_acceptflg_set(u8 value,
struct audit_buffer *audit_buf;
u8 old_val;

rcu_read_lock();
old_val = netlabel_unlabel_acceptflg;
spin_lock(&netlabel_unlabel_acceptflg_lock);
old_val = netlabel_unlabel_acceptflg;
netlabel_unlabel_acceptflg = value;
spin_unlock(&netlabel_unlabel_acceptflg_lock);
rcu_read_unlock();

audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_ALLOW,
audit_info);
Expand Down

0 comments on commit 4be2700

Please sign in to comment.