diff options
Diffstat (limited to 'net/llc/llc_core.c')
-rw-r--r-- | net/llc/llc_core.c | 53 |
1 files changed, 19 insertions, 34 deletions
diff --git a/net/llc/llc_core.c b/net/llc/llc_core.c index ff4c0ab96a6..78167e81dfe 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. |
@@ -33,40 +33,19 @@ DEFINE_RWLOCK(llc_sap_list_lock); | |||
33 | static struct llc_sap *llc_sap_alloc(void) | 33 | static struct llc_sap *llc_sap_alloc(void) |
34 | { | 34 | { |
35 | struct llc_sap *sap = kzalloc(sizeof(*sap), GFP_ATOMIC); | 35 | struct llc_sap *sap = kzalloc(sizeof(*sap), GFP_ATOMIC); |
36 | int i; | ||
36 | 37 | ||
37 | if (sap) { | 38 | if (sap) { |
38 | /* sap->laddr.mac - leave as a null, it's filled by bind */ | 39 | /* sap->laddr.mac - leave as a null, it's filled by bind */ |
39 | sap->state = LLC_SAP_STATE_ACTIVE; | 40 | sap->state = LLC_SAP_STATE_ACTIVE; |
40 | rwlock_init(&sap->sk_list.lock); | 41 | spin_lock_init(&sap->sk_lock); |
42 | for (i = 0; i < LLC_SK_LADDR_HASH_ENTRIES; i++) | ||
43 | INIT_HLIST_NULLS_HEAD(&sap->sk_laddr_hash[i], i); | ||
41 | atomic_set(&sap->refcnt, 1); | 44 | atomic_set(&sap->refcnt, 1); |
42 | } | 45 | } |
43 | return sap; | 46 | return sap; |
44 | } | 47 | } |
45 | 48 | ||
46 | /** | ||
47 | * llc_add_sap - add sap to station list | ||
48 | * @sap: Address of the sap | ||
49 | * | ||
50 | * Adds a sap to the LLC's station sap list. | ||
51 | */ | ||
52 | static void llc_add_sap(struct llc_sap *sap) | ||
53 | { | ||
54 | list_add_tail(&sap->node, &llc_sap_list); | ||
55 | } | ||
56 | |||
57 | /** | ||
58 | * llc_del_sap - del sap from station list | ||
59 | * @sap: Address of the sap | ||
60 | * | ||
61 | * Removes a sap to the LLC's station sap list. | ||
62 | */ | ||
63 | static void llc_del_sap(struct llc_sap *sap) | ||
64 | { | ||
65 | write_lock_bh(&llc_sap_list_lock); | ||
66 | list_del(&sap->node); | ||
67 | write_unlock_bh(&llc_sap_list_lock); | ||
68 | } | ||
69 | |||
70 | static struct llc_sap *__llc_sap_find(unsigned char sap_value) | 49 | static struct llc_sap *__llc_sap_find(unsigned char sap_value) |
71 | { | 50 | { |
72 | struct llc_sap* sap; | 51 | struct llc_sap* sap; |
@@ -90,13 +69,13 @@ out: | |||
90 | */ | 69 | */ |
91 | struct llc_sap *llc_sap_find(unsigned char sap_value) | 70 | struct llc_sap *llc_sap_find(unsigned char sap_value) |
92 | { | 71 | { |
93 | struct llc_sap* sap; | 72 | struct llc_sap *sap; |
94 | 73 | ||
95 | read_lock_bh(&llc_sap_list_lock); | 74 | rcu_read_lock_bh(); |
96 | sap = __llc_sap_find(sap_value); | 75 | sap = __llc_sap_find(sap_value); |
97 | if (sap) | 76 | if (sap) |
98 | llc_sap_hold(sap); | 77 | llc_sap_hold(sap); |
99 | read_unlock_bh(&llc_sap_list_lock); | 78 | rcu_read_unlock_bh(); |
100 | return sap; | 79 | return sap; |
101 | } | 80 | } |
102 | 81 | ||
@@ -117,7 +96,7 @@ struct llc_sap *llc_sap_open(unsigned char lsap, | |||
117 | { | 96 | { |
118 | struct llc_sap *sap = NULL; | 97 | struct llc_sap *sap = NULL; |
119 | 98 | ||
120 | write_lock_bh(&llc_sap_list_lock); | 99 | spin_lock_bh(&llc_sap_list_lock); |
121 | if (__llc_sap_find(lsap)) /* SAP already exists */ | 100 | if (__llc_sap_find(lsap)) /* SAP already exists */ |
122 | goto out; | 101 | goto out; |
123 | sap = llc_sap_alloc(); | 102 | sap = llc_sap_alloc(); |
@@ -125,9 +104,9 @@ struct llc_sap *llc_sap_open(unsigned char lsap, | |||
125 | goto out; | 104 | goto out; |
126 | sap->laddr.lsap = lsap; | 105 | sap->laddr.lsap = lsap; |
127 | sap->rcv_func = func; | 106 | sap->rcv_func = func; |
128 | llc_add_sap(sap); | 107 | list_add_tail_rcu(&sap->node, &llc_sap_list); |
129 | out: | 108 | out: |
130 | write_unlock_bh(&llc_sap_list_lock); | 109 | spin_unlock_bh(&llc_sap_list_lock); |
131 | return sap; | 110 | return sap; |
132 | } | 111 | } |
133 | 112 | ||
@@ -142,8 +121,14 @@ out: | |||
142 | */ | 121 | */ |
143 | void llc_sap_close(struct llc_sap *sap) | 122 | void llc_sap_close(struct llc_sap *sap) |
144 | { | 123 | { |
145 | WARN_ON(!hlist_empty(&sap->sk_list.list)); | 124 | WARN_ON(sap->sk_count); |
146 | 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 | |||
147 | kfree(sap); | 132 | kfree(sap); |
148 | } | 133 | } |
149 | 134 | ||