diff options
| author | Octavian Purdila <opurdila@ixiacom.com> | 2009-12-26 06:51:06 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2009-12-26 23:46:28 -0500 |
| commit | 8beb9ab6c2df203e8d68cb1f48cf42604a6bed86 (patch) | |
| tree | f342d582af0dd5f62016edcd2a50d2873ebcdbf2 /net/llc | |
| parent | 52d58aef5ee460fedd7f250f05e79081019f2c79 (diff) | |
llc: convert llc_sap_list to RCU
Signed-off-by: Octavian Purdila <opurdila@ixiacom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/llc')
| -rw-r--r-- | net/llc/llc_core.c | 46 | ||||
| -rw-r--r-- | net/llc/llc_proc.c | 11 |
2 files changed, 18 insertions, 39 deletions
diff --git a/net/llc/llc_core.c b/net/llc/llc_core.c index 0c9ef8bc7655..78167e81dfeb 100644 --- a/net/llc/llc_core.c +++ b/net/llc/llc_core.c | |||
| @@ -23,7 +23,7 @@ | |||
| 23 | #include <net/llc.h> | 23 | #include <net/llc.h> |
| 24 | 24 | ||
| 25 | LIST_HEAD(llc_sap_list); | 25 | LIST_HEAD(llc_sap_list); |
| 26 | DEFINE_RWLOCK(llc_sap_list_lock); | 26 | DEFINE_SPINLOCK(llc_sap_list_lock); |
| 27 | 27 | ||
| 28 | /** | 28 | /** |
| 29 | * llc_sap_alloc - allocates and initializes sap. | 29 | * llc_sap_alloc - allocates and initializes sap. |
| @@ -46,30 +46,6 @@ static struct llc_sap *llc_sap_alloc(void) | |||
| 46 | return sap; | 46 | return sap; |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | /** | ||
| 50 | * llc_add_sap - add sap to station list | ||
| 51 | * @sap: Address of the sap | ||
| 52 | * | ||
| 53 | * Adds a sap to the LLC's station sap list. | ||
| 54 | */ | ||
| 55 | static void llc_add_sap(struct llc_sap *sap) | ||
| 56 | { | ||
| 57 | list_add_tail(&sap->node, &llc_sap_list); | ||
| 58 | } | ||
| 59 | |||
| 60 | /** | ||
| 61 | * llc_del_sap - del sap from station list | ||
| 62 | * @sap: Address of the sap | ||
| 63 | * | ||
| 64 | * Removes a sap to the LLC's station sap list. | ||
| 65 | */ | ||
| 66 | static void llc_del_sap(struct llc_sap *sap) | ||
| 67 | { | ||
| 68 | write_lock_bh(&llc_sap_list_lock); | ||
| 69 | list_del(&sap->node); | ||
| 70 | write_unlock_bh(&llc_sap_list_lock); | ||
| 71 | } | ||
| 72 | |||
| 73 | static struct llc_sap *__llc_sap_find(unsigned char sap_value) | 49 | static struct llc_sap *__llc_sap_find(unsigned char sap_value) |
| 74 | { | 50 | { |
| 75 | struct llc_sap* sap; | 51 | struct llc_sap* sap; |
| @@ -93,13 +69,13 @@ out: | |||
| 93 | */ | 69 | */ |
| 94 | struct llc_sap *llc_sap_find(unsigned char sap_value) | 70 | struct llc_sap *llc_sap_find(unsigned char sap_value) |
| 95 | { | 71 | { |
| 96 | struct llc_sap* sap; | 72 | struct llc_sap *sap; |
| 97 | 73 | ||
| 98 | read_lock_bh(&llc_sap_list_lock); | 74 | rcu_read_lock_bh(); |
| 99 | sap = __llc_sap_find(sap_value); | 75 | sap = __llc_sap_find(sap_value); |
| 100 | if (sap) | 76 | if (sap) |
| 101 | llc_sap_hold(sap); | 77 | llc_sap_hold(sap); |
| 102 | read_unlock_bh(&llc_sap_list_lock); | 78 | rcu_read_unlock_bh(); |
| 103 | return sap; | 79 | return sap; |
| 104 | } | 80 | } |
| 105 | 81 | ||
| @@ -120,7 +96,7 @@ struct llc_sap *llc_sap_open(unsigned char lsap, | |||
| 120 | { | 96 | { |
| 121 | struct llc_sap *sap = NULL; | 97 | struct llc_sap *sap = NULL; |
| 122 | 98 | ||
| 123 | write_lock_bh(&llc_sap_list_lock); | 99 | spin_lock_bh(&llc_sap_list_lock); |
| 124 | if (__llc_sap_find(lsap)) /* SAP already exists */ | 100 | if (__llc_sap_find(lsap)) /* SAP already exists */ |
| 125 | goto out; | 101 | goto out; |
| 126 | sap = llc_sap_alloc(); | 102 | sap = llc_sap_alloc(); |
| @@ -128,9 +104,9 @@ struct llc_sap *llc_sap_open(unsigned char lsap, | |||
| 128 | goto out; | 104 | goto out; |
| 129 | sap->laddr.lsap = lsap; | 105 | sap->laddr.lsap = lsap; |
| 130 | sap->rcv_func = func; | 106 | sap->rcv_func = func; |
| 131 | llc_add_sap(sap); | 107 | list_add_tail_rcu(&sap->node, &llc_sap_list); |
| 132 | out: | 108 | out: |
| 133 | write_unlock_bh(&llc_sap_list_lock); | 109 | spin_unlock_bh(&llc_sap_list_lock); |
| 134 | return sap; | 110 | return sap; |
| 135 | } | 111 | } |
| 136 | 112 | ||
| @@ -146,7 +122,13 @@ out: | |||
| 146 | void llc_sap_close(struct llc_sap *sap) | 122 | void llc_sap_close(struct llc_sap *sap) |
| 147 | { | 123 | { |
| 148 | WARN_ON(sap->sk_count); | 124 | WARN_ON(sap->sk_count); |
| 149 | llc_del_sap(sap); | 125 | |
| 126 | spin_lock_bh(&llc_sap_list_lock); | ||
| 127 | list_del_rcu(&sap->node); | ||
| 128 | spin_unlock_bh(&llc_sap_list_lock); | ||
| 129 | |||
| 130 | synchronize_rcu(); | ||
| 131 | |||
| 150 | kfree(sap); | 132 | kfree(sap); |
| 151 | } | 133 | } |
| 152 | 134 | ||
diff --git a/net/llc/llc_proc.c b/net/llc/llc_proc.c index 09dec6307206..7af1ff2d1f19 100644 --- a/net/llc/llc_proc.c +++ b/net/llc/llc_proc.c | |||
| @@ -32,14 +32,11 @@ static void llc_ui_format_mac(struct seq_file *seq, u8 *addr) | |||
| 32 | 32 | ||
| 33 | static struct sock *llc_get_sk_idx(loff_t pos) | 33 | static struct sock *llc_get_sk_idx(loff_t pos) |
| 34 | { | 34 | { |
| 35 | struct list_head *sap_entry; | ||
| 36 | struct llc_sap *sap; | 35 | struct llc_sap *sap; |
| 37 | struct sock *sk = NULL; | 36 | struct sock *sk = NULL; |
| 38 | int i; | 37 | int i; |
| 39 | 38 | ||
| 40 | list_for_each(sap_entry, &llc_sap_list) { | 39 | list_for_each_entry_rcu(sap, &llc_sap_list, node) { |
| 41 | sap = list_entry(sap_entry, struct llc_sap, node); | ||
| 42 | |||
| 43 | spin_lock_bh(&sap->sk_lock); | 40 | spin_lock_bh(&sap->sk_lock); |
| 44 | for (i = 0; i < LLC_SK_LADDR_HASH_ENTRIES; i++) { | 41 | for (i = 0; i < LLC_SK_LADDR_HASH_ENTRIES; i++) { |
| 45 | struct hlist_nulls_head *head = &sap->sk_laddr_hash[i]; | 42 | struct hlist_nulls_head *head = &sap->sk_laddr_hash[i]; |
| @@ -62,7 +59,7 @@ static void *llc_seq_start(struct seq_file *seq, loff_t *pos) | |||
| 62 | { | 59 | { |
| 63 | loff_t l = *pos; | 60 | loff_t l = *pos; |
| 64 | 61 | ||
| 65 | read_lock_bh(&llc_sap_list_lock); | 62 | rcu_read_lock_bh(); |
| 66 | return l ? llc_get_sk_idx(--l) : SEQ_START_TOKEN; | 63 | return l ? llc_get_sk_idx(--l) : SEQ_START_TOKEN; |
| 67 | } | 64 | } |
| 68 | 65 | ||
| @@ -102,7 +99,7 @@ static void *llc_seq_next(struct seq_file *seq, void *v, loff_t *pos) | |||
| 102 | if (sk) | 99 | if (sk) |
| 103 | goto out; | 100 | goto out; |
| 104 | spin_unlock_bh(&sap->sk_lock); | 101 | spin_unlock_bh(&sap->sk_lock); |
| 105 | list_for_each_entry_continue(sap, &llc_sap_list, node) { | 102 | list_for_each_entry_continue_rcu(sap, &llc_sap_list, node) { |
| 106 | spin_lock_bh(&sap->sk_lock); | 103 | spin_lock_bh(&sap->sk_lock); |
| 107 | sk = laddr_hash_next(sap, -1); | 104 | sk = laddr_hash_next(sap, -1); |
| 108 | if (sk) | 105 | if (sk) |
| @@ -122,7 +119,7 @@ static void llc_seq_stop(struct seq_file *seq, void *v) | |||
| 122 | 119 | ||
| 123 | spin_unlock_bh(&sap->sk_lock); | 120 | spin_unlock_bh(&sap->sk_lock); |
| 124 | } | 121 | } |
| 125 | read_unlock_bh(&llc_sap_list_lock); | 122 | rcu_read_unlock_bh(); |
| 126 | } | 123 | } |
| 127 | 124 | ||
| 128 | static int llc_seq_socket_show(struct seq_file *seq, void *v) | 125 | static int llc_seq_socket_show(struct seq_file *seq, void *v) |
