diff options
author | David S. Miller <davem@davemloft.net> | 2017-01-28 10:33:06 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-01-28 10:33:06 -0500 |
commit | 4e8f2fc1a55d543717efb70e170b09e773d0542b (patch) | |
tree | 30df1d7fc9dfa24fe2916711a17656682c3f7ec9 /net/tipc | |
parent | 158f323b9868b59967ad96957c4ca388161be321 (diff) | |
parent | 1b1bc42c1692e9b62756323c675a44cb1a1f9dbd (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Two trivial overlapping changes conflicts in MPLS and mlx5.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc')
-rw-r--r-- | net/tipc/node.c | 9 | ||||
-rw-r--r-- | net/tipc/server.c | 48 | ||||
-rw-r--r-- | net/tipc/subscr.c | 124 | ||||
-rw-r--r-- | net/tipc/subscr.h | 1 |
4 files changed, 99 insertions, 83 deletions
diff --git a/net/tipc/node.c b/net/tipc/node.c index f96dacf173ab..e9295fa3a554 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c | |||
@@ -263,6 +263,11 @@ static void tipc_node_write_lock(struct tipc_node *n) | |||
263 | write_lock_bh(&n->lock); | 263 | write_lock_bh(&n->lock); |
264 | } | 264 | } |
265 | 265 | ||
266 | static void tipc_node_write_unlock_fast(struct tipc_node *n) | ||
267 | { | ||
268 | write_unlock_bh(&n->lock); | ||
269 | } | ||
270 | |||
266 | static void tipc_node_write_unlock(struct tipc_node *n) | 271 | static void tipc_node_write_unlock(struct tipc_node *n) |
267 | { | 272 | { |
268 | struct net *net = n->net; | 273 | struct net *net = n->net; |
@@ -417,7 +422,7 @@ void tipc_node_subscribe(struct net *net, struct list_head *subscr, u32 addr) | |||
417 | } | 422 | } |
418 | tipc_node_write_lock(n); | 423 | tipc_node_write_lock(n); |
419 | list_add_tail(subscr, &n->publ_list); | 424 | list_add_tail(subscr, &n->publ_list); |
420 | tipc_node_write_unlock(n); | 425 | tipc_node_write_unlock_fast(n); |
421 | tipc_node_put(n); | 426 | tipc_node_put(n); |
422 | } | 427 | } |
423 | 428 | ||
@@ -435,7 +440,7 @@ void tipc_node_unsubscribe(struct net *net, struct list_head *subscr, u32 addr) | |||
435 | } | 440 | } |
436 | tipc_node_write_lock(n); | 441 | tipc_node_write_lock(n); |
437 | list_del_init(subscr); | 442 | list_del_init(subscr); |
438 | tipc_node_write_unlock(n); | 443 | tipc_node_write_unlock_fast(n); |
439 | tipc_node_put(n); | 444 | tipc_node_put(n); |
440 | } | 445 | } |
441 | 446 | ||
diff --git a/net/tipc/server.c b/net/tipc/server.c index 215849ce453d..3cd6402e812c 100644 --- a/net/tipc/server.c +++ b/net/tipc/server.c | |||
@@ -86,12 +86,12 @@ struct outqueue_entry { | |||
86 | static void tipc_recv_work(struct work_struct *work); | 86 | static void tipc_recv_work(struct work_struct *work); |
87 | static void tipc_send_work(struct work_struct *work); | 87 | static void tipc_send_work(struct work_struct *work); |
88 | static void tipc_clean_outqueues(struct tipc_conn *con); | 88 | static void tipc_clean_outqueues(struct tipc_conn *con); |
89 | static void tipc_sock_release(struct tipc_conn *con); | ||
90 | 89 | ||
91 | static void tipc_conn_kref_release(struct kref *kref) | 90 | static void tipc_conn_kref_release(struct kref *kref) |
92 | { | 91 | { |
93 | struct tipc_conn *con = container_of(kref, struct tipc_conn, kref); | 92 | struct tipc_conn *con = container_of(kref, struct tipc_conn, kref); |
94 | struct sockaddr_tipc *saddr = con->server->saddr; | 93 | struct tipc_server *s = con->server; |
94 | struct sockaddr_tipc *saddr = s->saddr; | ||
95 | struct socket *sock = con->sock; | 95 | struct socket *sock = con->sock; |
96 | struct sock *sk; | 96 | struct sock *sk; |
97 | 97 | ||
@@ -103,9 +103,13 @@ static void tipc_conn_kref_release(struct kref *kref) | |||
103 | } | 103 | } |
104 | saddr->scope = -TIPC_NODE_SCOPE; | 104 | saddr->scope = -TIPC_NODE_SCOPE; |
105 | kernel_bind(sock, (struct sockaddr *)saddr, sizeof(*saddr)); | 105 | kernel_bind(sock, (struct sockaddr *)saddr, sizeof(*saddr)); |
106 | tipc_sock_release(con); | ||
107 | sock_release(sock); | 106 | sock_release(sock); |
108 | con->sock = NULL; | 107 | con->sock = NULL; |
108 | |||
109 | spin_lock_bh(&s->idr_lock); | ||
110 | idr_remove(&s->conn_idr, con->conid); | ||
111 | s->idr_in_use--; | ||
112 | spin_unlock_bh(&s->idr_lock); | ||
109 | } | 113 | } |
110 | 114 | ||
111 | tipc_clean_outqueues(con); | 115 | tipc_clean_outqueues(con); |
@@ -128,8 +132,10 @@ static struct tipc_conn *tipc_conn_lookup(struct tipc_server *s, int conid) | |||
128 | 132 | ||
129 | spin_lock_bh(&s->idr_lock); | 133 | spin_lock_bh(&s->idr_lock); |
130 | con = idr_find(&s->conn_idr, conid); | 134 | con = idr_find(&s->conn_idr, conid); |
131 | if (con) | 135 | if (con && test_bit(CF_CONNECTED, &con->flags)) |
132 | conn_get(con); | 136 | conn_get(con); |
137 | else | ||
138 | con = NULL; | ||
133 | spin_unlock_bh(&s->idr_lock); | 139 | spin_unlock_bh(&s->idr_lock); |
134 | return con; | 140 | return con; |
135 | } | 141 | } |
@@ -186,26 +192,15 @@ static void tipc_unregister_callbacks(struct tipc_conn *con) | |||
186 | write_unlock_bh(&sk->sk_callback_lock); | 192 | write_unlock_bh(&sk->sk_callback_lock); |
187 | } | 193 | } |
188 | 194 | ||
189 | static void tipc_sock_release(struct tipc_conn *con) | ||
190 | { | ||
191 | struct tipc_server *s = con->server; | ||
192 | |||
193 | if (con->conid) | ||
194 | s->tipc_conn_release(con->conid, con->usr_data); | ||
195 | |||
196 | tipc_unregister_callbacks(con); | ||
197 | } | ||
198 | |||
199 | static void tipc_close_conn(struct tipc_conn *con) | 195 | static void tipc_close_conn(struct tipc_conn *con) |
200 | { | 196 | { |
201 | struct tipc_server *s = con->server; | 197 | struct tipc_server *s = con->server; |
202 | 198 | ||
203 | if (test_and_clear_bit(CF_CONNECTED, &con->flags)) { | 199 | if (test_and_clear_bit(CF_CONNECTED, &con->flags)) { |
200 | tipc_unregister_callbacks(con); | ||
204 | 201 | ||
205 | spin_lock_bh(&s->idr_lock); | 202 | if (con->conid) |
206 | idr_remove(&s->conn_idr, con->conid); | 203 | s->tipc_conn_release(con->conid, con->usr_data); |
207 | s->idr_in_use--; | ||
208 | spin_unlock_bh(&s->idr_lock); | ||
209 | 204 | ||
210 | /* We shouldn't flush pending works as we may be in the | 205 | /* We shouldn't flush pending works as we may be in the |
211 | * thread. In fact the races with pending rx/tx work structs | 206 | * thread. In fact the races with pending rx/tx work structs |
@@ -458,6 +453,11 @@ int tipc_conn_sendmsg(struct tipc_server *s, int conid, | |||
458 | if (!con) | 453 | if (!con) |
459 | return -EINVAL; | 454 | return -EINVAL; |
460 | 455 | ||
456 | if (!test_bit(CF_CONNECTED, &con->flags)) { | ||
457 | conn_put(con); | ||
458 | return 0; | ||
459 | } | ||
460 | |||
461 | e = tipc_alloc_entry(data, len); | 461 | e = tipc_alloc_entry(data, len); |
462 | if (!e) { | 462 | if (!e) { |
463 | conn_put(con); | 463 | conn_put(con); |
@@ -471,12 +471,8 @@ int tipc_conn_sendmsg(struct tipc_server *s, int conid, | |||
471 | list_add_tail(&e->list, &con->outqueue); | 471 | list_add_tail(&e->list, &con->outqueue); |
472 | spin_unlock_bh(&con->outqueue_lock); | 472 | spin_unlock_bh(&con->outqueue_lock); |
473 | 473 | ||
474 | if (test_bit(CF_CONNECTED, &con->flags)) { | 474 | if (!queue_work(s->send_wq, &con->swork)) |
475 | if (!queue_work(s->send_wq, &con->swork)) | ||
476 | conn_put(con); | ||
477 | } else { | ||
478 | conn_put(con); | 475 | conn_put(con); |
479 | } | ||
480 | return 0; | 476 | return 0; |
481 | } | 477 | } |
482 | 478 | ||
@@ -500,7 +496,7 @@ static void tipc_send_to_sock(struct tipc_conn *con) | |||
500 | int ret; | 496 | int ret; |
501 | 497 | ||
502 | spin_lock_bh(&con->outqueue_lock); | 498 | spin_lock_bh(&con->outqueue_lock); |
503 | while (1) { | 499 | while (test_bit(CF_CONNECTED, &con->flags)) { |
504 | e = list_entry(con->outqueue.next, struct outqueue_entry, | 500 | e = list_entry(con->outqueue.next, struct outqueue_entry, |
505 | list); | 501 | list); |
506 | if ((struct list_head *) e == &con->outqueue) | 502 | if ((struct list_head *) e == &con->outqueue) |
@@ -623,14 +619,12 @@ int tipc_server_start(struct tipc_server *s) | |||
623 | void tipc_server_stop(struct tipc_server *s) | 619 | void tipc_server_stop(struct tipc_server *s) |
624 | { | 620 | { |
625 | struct tipc_conn *con; | 621 | struct tipc_conn *con; |
626 | int total = 0; | ||
627 | int id; | 622 | int id; |
628 | 623 | ||
629 | spin_lock_bh(&s->idr_lock); | 624 | spin_lock_bh(&s->idr_lock); |
630 | for (id = 0; total < s->idr_in_use; id++) { | 625 | for (id = 0; s->idr_in_use; id++) { |
631 | con = idr_find(&s->conn_idr, id); | 626 | con = idr_find(&s->conn_idr, id); |
632 | if (con) { | 627 | if (con) { |
633 | total++; | ||
634 | spin_unlock_bh(&s->idr_lock); | 628 | spin_unlock_bh(&s->idr_lock); |
635 | tipc_close_conn(con); | 629 | tipc_close_conn(con); |
636 | spin_lock_bh(&s->idr_lock); | 630 | spin_lock_bh(&s->idr_lock); |
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index 0dd02244e21d..9d94e65d0894 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c | |||
@@ -54,6 +54,8 @@ struct tipc_subscriber { | |||
54 | 54 | ||
55 | static void tipc_subscrp_delete(struct tipc_subscription *sub); | 55 | static void tipc_subscrp_delete(struct tipc_subscription *sub); |
56 | static void tipc_subscrb_put(struct tipc_subscriber *subscriber); | 56 | static void tipc_subscrb_put(struct tipc_subscriber *subscriber); |
57 | static void tipc_subscrp_put(struct tipc_subscription *subscription); | ||
58 | static void tipc_subscrp_get(struct tipc_subscription *subscription); | ||
57 | 59 | ||
58 | /** | 60 | /** |
59 | * htohl - convert value to endianness used by destination | 61 | * htohl - convert value to endianness used by destination |
@@ -123,6 +125,7 @@ void tipc_subscrp_report_overlap(struct tipc_subscription *sub, u32 found_lower, | |||
123 | { | 125 | { |
124 | struct tipc_name_seq seq; | 126 | struct tipc_name_seq seq; |
125 | 127 | ||
128 | tipc_subscrp_get(sub); | ||
126 | tipc_subscrp_convert_seq(&sub->evt.s.seq, sub->swap, &seq); | 129 | tipc_subscrp_convert_seq(&sub->evt.s.seq, sub->swap, &seq); |
127 | if (!tipc_subscrp_check_overlap(&seq, found_lower, found_upper)) | 130 | if (!tipc_subscrp_check_overlap(&seq, found_lower, found_upper)) |
128 | return; | 131 | return; |
@@ -132,30 +135,23 @@ void tipc_subscrp_report_overlap(struct tipc_subscription *sub, u32 found_lower, | |||
132 | 135 | ||
133 | tipc_subscrp_send_event(sub, found_lower, found_upper, event, port_ref, | 136 | tipc_subscrp_send_event(sub, found_lower, found_upper, event, port_ref, |
134 | node); | 137 | node); |
138 | tipc_subscrp_put(sub); | ||
135 | } | 139 | } |
136 | 140 | ||
137 | static void tipc_subscrp_timeout(unsigned long data) | 141 | static void tipc_subscrp_timeout(unsigned long data) |
138 | { | 142 | { |
139 | struct tipc_subscription *sub = (struct tipc_subscription *)data; | 143 | struct tipc_subscription *sub = (struct tipc_subscription *)data; |
140 | struct tipc_subscriber *subscriber = sub->subscriber; | ||
141 | 144 | ||
142 | /* Notify subscriber of timeout */ | 145 | /* Notify subscriber of timeout */ |
143 | tipc_subscrp_send_event(sub, sub->evt.s.seq.lower, sub->evt.s.seq.upper, | 146 | tipc_subscrp_send_event(sub, sub->evt.s.seq.lower, sub->evt.s.seq.upper, |
144 | TIPC_SUBSCR_TIMEOUT, 0, 0); | 147 | TIPC_SUBSCR_TIMEOUT, 0, 0); |
145 | 148 | ||
146 | spin_lock_bh(&subscriber->lock); | 149 | tipc_subscrp_put(sub); |
147 | tipc_subscrp_delete(sub); | ||
148 | spin_unlock_bh(&subscriber->lock); | ||
149 | |||
150 | tipc_subscrb_put(subscriber); | ||
151 | } | 150 | } |
152 | 151 | ||
153 | static void tipc_subscrb_kref_release(struct kref *kref) | 152 | static void tipc_subscrb_kref_release(struct kref *kref) |
154 | { | 153 | { |
155 | struct tipc_subscriber *subcriber = container_of(kref, | 154 | kfree(container_of(kref,struct tipc_subscriber, kref)); |
156 | struct tipc_subscriber, kref); | ||
157 | |||
158 | kfree(subcriber); | ||
159 | } | 155 | } |
160 | 156 | ||
161 | static void tipc_subscrb_put(struct tipc_subscriber *subscriber) | 157 | static void tipc_subscrb_put(struct tipc_subscriber *subscriber) |
@@ -168,6 +164,59 @@ static void tipc_subscrb_get(struct tipc_subscriber *subscriber) | |||
168 | kref_get(&subscriber->kref); | 164 | kref_get(&subscriber->kref); |
169 | } | 165 | } |
170 | 166 | ||
167 | static void tipc_subscrp_kref_release(struct kref *kref) | ||
168 | { | ||
169 | struct tipc_subscription *sub = container_of(kref, | ||
170 | struct tipc_subscription, | ||
171 | kref); | ||
172 | struct tipc_net *tn = net_generic(sub->net, tipc_net_id); | ||
173 | struct tipc_subscriber *subscriber = sub->subscriber; | ||
174 | |||
175 | spin_lock_bh(&subscriber->lock); | ||
176 | tipc_nametbl_unsubscribe(sub); | ||
177 | list_del(&sub->subscrp_list); | ||
178 | atomic_dec(&tn->subscription_count); | ||
179 | spin_unlock_bh(&subscriber->lock); | ||
180 | kfree(sub); | ||
181 | tipc_subscrb_put(subscriber); | ||
182 | } | ||
183 | |||
184 | static void tipc_subscrp_put(struct tipc_subscription *subscription) | ||
185 | { | ||
186 | kref_put(&subscription->kref, tipc_subscrp_kref_release); | ||
187 | } | ||
188 | |||
189 | static void tipc_subscrp_get(struct tipc_subscription *subscription) | ||
190 | { | ||
191 | kref_get(&subscription->kref); | ||
192 | } | ||
193 | |||
194 | /* tipc_subscrb_subscrp_delete - delete a specific subscription or all | ||
195 | * subscriptions for a given subscriber. | ||
196 | */ | ||
197 | static void tipc_subscrb_subscrp_delete(struct tipc_subscriber *subscriber, | ||
198 | struct tipc_subscr *s) | ||
199 | { | ||
200 | struct list_head *subscription_list = &subscriber->subscrp_list; | ||
201 | struct tipc_subscription *sub, *temp; | ||
202 | |||
203 | spin_lock_bh(&subscriber->lock); | ||
204 | list_for_each_entry_safe(sub, temp, subscription_list, subscrp_list) { | ||
205 | if (s && memcmp(s, &sub->evt.s, sizeof(struct tipc_subscr))) | ||
206 | continue; | ||
207 | |||
208 | tipc_subscrp_get(sub); | ||
209 | spin_unlock_bh(&subscriber->lock); | ||
210 | tipc_subscrp_delete(sub); | ||
211 | tipc_subscrp_put(sub); | ||
212 | spin_lock_bh(&subscriber->lock); | ||
213 | |||
214 | if (s) | ||
215 | break; | ||
216 | } | ||
217 | spin_unlock_bh(&subscriber->lock); | ||
218 | } | ||
219 | |||
171 | static struct tipc_subscriber *tipc_subscrb_create(int conid) | 220 | static struct tipc_subscriber *tipc_subscrb_create(int conid) |
172 | { | 221 | { |
173 | struct tipc_subscriber *subscriber; | 222 | struct tipc_subscriber *subscriber; |
@@ -177,8 +226,8 @@ static struct tipc_subscriber *tipc_subscrb_create(int conid) | |||
177 | pr_warn("Subscriber rejected, no memory\n"); | 226 | pr_warn("Subscriber rejected, no memory\n"); |
178 | return NULL; | 227 | return NULL; |
179 | } | 228 | } |
180 | kref_init(&subscriber->kref); | ||
181 | INIT_LIST_HEAD(&subscriber->subscrp_list); | 229 | INIT_LIST_HEAD(&subscriber->subscrp_list); |
230 | kref_init(&subscriber->kref); | ||
182 | subscriber->conid = conid; | 231 | subscriber->conid = conid; |
183 | spin_lock_init(&subscriber->lock); | 232 | spin_lock_init(&subscriber->lock); |
184 | 233 | ||
@@ -187,55 +236,22 @@ static struct tipc_subscriber *tipc_subscrb_create(int conid) | |||
187 | 236 | ||
188 | static void tipc_subscrb_delete(struct tipc_subscriber *subscriber) | 237 | static void tipc_subscrb_delete(struct tipc_subscriber *subscriber) |
189 | { | 238 | { |
190 | struct tipc_subscription *sub, *temp; | 239 | tipc_subscrb_subscrp_delete(subscriber, NULL); |
191 | u32 timeout; | ||
192 | |||
193 | spin_lock_bh(&subscriber->lock); | ||
194 | /* Destroy any existing subscriptions for subscriber */ | ||
195 | list_for_each_entry_safe(sub, temp, &subscriber->subscrp_list, | ||
196 | subscrp_list) { | ||
197 | timeout = htohl(sub->evt.s.timeout, sub->swap); | ||
198 | if ((timeout == TIPC_WAIT_FOREVER) || del_timer(&sub->timer)) { | ||
199 | tipc_subscrp_delete(sub); | ||
200 | tipc_subscrb_put(subscriber); | ||
201 | } | ||
202 | } | ||
203 | spin_unlock_bh(&subscriber->lock); | ||
204 | |||
205 | tipc_subscrb_put(subscriber); | 240 | tipc_subscrb_put(subscriber); |
206 | } | 241 | } |
207 | 242 | ||
208 | static void tipc_subscrp_delete(struct tipc_subscription *sub) | 243 | static void tipc_subscrp_delete(struct tipc_subscription *sub) |
209 | { | 244 | { |
210 | struct tipc_net *tn = net_generic(sub->net, tipc_net_id); | 245 | u32 timeout = htohl(sub->evt.s.timeout, sub->swap); |
211 | 246 | ||
212 | tipc_nametbl_unsubscribe(sub); | 247 | if (timeout == TIPC_WAIT_FOREVER || del_timer(&sub->timer)) |
213 | list_del(&sub->subscrp_list); | 248 | tipc_subscrp_put(sub); |
214 | kfree(sub); | ||
215 | atomic_dec(&tn->subscription_count); | ||
216 | } | 249 | } |
217 | 250 | ||
218 | static void tipc_subscrp_cancel(struct tipc_subscr *s, | 251 | static void tipc_subscrp_cancel(struct tipc_subscr *s, |
219 | struct tipc_subscriber *subscriber) | 252 | struct tipc_subscriber *subscriber) |
220 | { | 253 | { |
221 | struct tipc_subscription *sub, *temp; | 254 | tipc_subscrb_subscrp_delete(subscriber, s); |
222 | u32 timeout; | ||
223 | |||
224 | spin_lock_bh(&subscriber->lock); | ||
225 | /* Find first matching subscription, exit if not found */ | ||
226 | list_for_each_entry_safe(sub, temp, &subscriber->subscrp_list, | ||
227 | subscrp_list) { | ||
228 | if (!memcmp(s, &sub->evt.s, sizeof(struct tipc_subscr))) { | ||
229 | timeout = htohl(sub->evt.s.timeout, sub->swap); | ||
230 | if ((timeout == TIPC_WAIT_FOREVER) || | ||
231 | del_timer(&sub->timer)) { | ||
232 | tipc_subscrp_delete(sub); | ||
233 | tipc_subscrb_put(subscriber); | ||
234 | } | ||
235 | break; | ||
236 | } | ||
237 | } | ||
238 | spin_unlock_bh(&subscriber->lock); | ||
239 | } | 255 | } |
240 | 256 | ||
241 | static struct tipc_subscription *tipc_subscrp_create(struct net *net, | 257 | static struct tipc_subscription *tipc_subscrp_create(struct net *net, |
@@ -272,6 +288,7 @@ static struct tipc_subscription *tipc_subscrp_create(struct net *net, | |||
272 | sub->swap = swap; | 288 | sub->swap = swap; |
273 | memcpy(&sub->evt.s, s, sizeof(*s)); | 289 | memcpy(&sub->evt.s, s, sizeof(*s)); |
274 | atomic_inc(&tn->subscription_count); | 290 | atomic_inc(&tn->subscription_count); |
291 | kref_init(&sub->kref); | ||
275 | return sub; | 292 | return sub; |
276 | } | 293 | } |
277 | 294 | ||
@@ -288,17 +305,16 @@ static void tipc_subscrp_subscribe(struct net *net, struct tipc_subscr *s, | |||
288 | 305 | ||
289 | spin_lock_bh(&subscriber->lock); | 306 | spin_lock_bh(&subscriber->lock); |
290 | list_add(&sub->subscrp_list, &subscriber->subscrp_list); | 307 | list_add(&sub->subscrp_list, &subscriber->subscrp_list); |
291 | tipc_subscrb_get(subscriber); | ||
292 | sub->subscriber = subscriber; | 308 | sub->subscriber = subscriber; |
293 | tipc_nametbl_subscribe(sub); | 309 | tipc_nametbl_subscribe(sub); |
310 | tipc_subscrb_get(subscriber); | ||
294 | spin_unlock_bh(&subscriber->lock); | 311 | spin_unlock_bh(&subscriber->lock); |
295 | 312 | ||
313 | setup_timer(&sub->timer, tipc_subscrp_timeout, (unsigned long)sub); | ||
296 | timeout = htohl(sub->evt.s.timeout, swap); | 314 | timeout = htohl(sub->evt.s.timeout, swap); |
297 | if (timeout == TIPC_WAIT_FOREVER) | ||
298 | return; | ||
299 | 315 | ||
300 | setup_timer(&sub->timer, tipc_subscrp_timeout, (unsigned long)sub); | 316 | if (timeout != TIPC_WAIT_FOREVER) |
301 | mod_timer(&sub->timer, jiffies + msecs_to_jiffies(timeout)); | 317 | mod_timer(&sub->timer, jiffies + msecs_to_jiffies(timeout)); |
302 | } | 318 | } |
303 | 319 | ||
304 | /* Handle one termination request for the subscriber */ | 320 | /* Handle one termination request for the subscriber */ |
diff --git a/net/tipc/subscr.h b/net/tipc/subscr.h index be60103082c9..ffdc214c117a 100644 --- a/net/tipc/subscr.h +++ b/net/tipc/subscr.h | |||
@@ -57,6 +57,7 @@ struct tipc_subscriber; | |||
57 | * @evt: template for events generated by subscription | 57 | * @evt: template for events generated by subscription |
58 | */ | 58 | */ |
59 | struct tipc_subscription { | 59 | struct tipc_subscription { |
60 | struct kref kref; | ||
60 | struct tipc_subscriber *subscriber; | 61 | struct tipc_subscriber *subscriber; |
61 | struct net *net; | 62 | struct net *net; |
62 | struct timer_list timer; | 63 | struct timer_list timer; |