diff options
-rw-r--r-- | Documentation/sysctl/net.txt | 16 | ||||
-rw-r--r-- | net/tipc/core.h | 1 | ||||
-rw-r--r-- | net/tipc/name_distr.c | 69 | ||||
-rw-r--r-- | net/tipc/name_distr.h | 1 | ||||
-rw-r--r-- | net/tipc/name_table.c | 8 | ||||
-rw-r--r-- | net/tipc/sysctl.c | 7 |
6 files changed, 95 insertions, 7 deletions
diff --git a/Documentation/sysctl/net.txt b/Documentation/sysctl/net.txt index 9a0319a82470..04892b821157 100644 --- a/Documentation/sysctl/net.txt +++ b/Documentation/sysctl/net.txt | |||
@@ -241,6 +241,9 @@ address of the router (or Connected) for internal networks. | |||
241 | 6. TIPC | 241 | 6. TIPC |
242 | ------------------------------------------------------- | 242 | ------------------------------------------------------- |
243 | 243 | ||
244 | tipc_rmem | ||
245 | ---------- | ||
246 | |||
244 | The TIPC protocol now has a tunable for the receive memory, similar to the | 247 | The TIPC protocol now has a tunable for the receive memory, similar to the |
245 | tcp_rmem - i.e. a vector of 3 INTEGERs: (min, default, max) | 248 | tcp_rmem - i.e. a vector of 3 INTEGERs: (min, default, max) |
246 | 249 | ||
@@ -252,3 +255,16 @@ The max value is set to CONN_OVERLOAD_LIMIT, and the default and min values | |||
252 | are scaled (shifted) versions of that same value. Note that the min value | 255 | are scaled (shifted) versions of that same value. Note that the min value |
253 | is not at this point in time used in any meaningful way, but the triplet is | 256 | is not at this point in time used in any meaningful way, but the triplet is |
254 | preserved in order to be consistent with things like tcp_rmem. | 257 | preserved in order to be consistent with things like tcp_rmem. |
258 | |||
259 | named_timeout | ||
260 | -------------- | ||
261 | |||
262 | TIPC name table updates are distributed asynchronously in a cluster, without | ||
263 | any form of transaction handling. This means that different race scenarios are | ||
264 | possible. One such is that a name withdrawal sent out by one node and received | ||
265 | by another node may arrive after a second, overlapping name publication already | ||
266 | has been accepted from a third node, although the conflicting updates | ||
267 | originally may have been issued in the correct sequential order. | ||
268 | If named_timeout is nonzero, failed topology updates will be placed on a defer | ||
269 | queue until another event arrives that clears the error, or until the timeout | ||
270 | expires. Value is in milliseconds. | ||
diff --git a/net/tipc/core.h b/net/tipc/core.h index d2607a8e2b80..f773b148722f 100644 --- a/net/tipc/core.h +++ b/net/tipc/core.h | |||
@@ -81,6 +81,7 @@ extern u32 tipc_own_addr __read_mostly; | |||
81 | extern int tipc_max_ports __read_mostly; | 81 | extern int tipc_max_ports __read_mostly; |
82 | extern int tipc_net_id __read_mostly; | 82 | extern int tipc_net_id __read_mostly; |
83 | extern int sysctl_tipc_rmem[3] __read_mostly; | 83 | extern int sysctl_tipc_rmem[3] __read_mostly; |
84 | extern int sysctl_tipc_named_timeout __read_mostly; | ||
84 | 85 | ||
85 | /* | 86 | /* |
86 | * Other global variables | 87 | * Other global variables |
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c index 0591f33b8384..780ef710a849 100644 --- a/net/tipc/name_distr.c +++ b/net/tipc/name_distr.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * net/tipc/name_distr.c: TIPC name distribution code | 2 | * net/tipc/name_distr.c: TIPC name distribution code |
3 | * | 3 | * |
4 | * Copyright (c) 2000-2006, Ericsson AB | 4 | * Copyright (c) 2000-2006, 2014, Ericsson AB |
5 | * Copyright (c) 2005, 2010-2011, Wind River Systems | 5 | * Copyright (c) 2005, 2010-2011, Wind River Systems |
6 | * All rights reserved. | 6 | * All rights reserved. |
7 | * | 7 | * |
@@ -71,6 +71,21 @@ static struct publ_list *publ_lists[] = { | |||
71 | }; | 71 | }; |
72 | 72 | ||
73 | 73 | ||
74 | int sysctl_tipc_named_timeout __read_mostly = 2000; | ||
75 | |||
76 | /** | ||
77 | * struct tipc_dist_queue - queue holding deferred name table updates | ||
78 | */ | ||
79 | static struct list_head tipc_dist_queue = LIST_HEAD_INIT(tipc_dist_queue); | ||
80 | |||
81 | struct distr_queue_item { | ||
82 | struct distr_item i; | ||
83 | u32 dtype; | ||
84 | u32 node; | ||
85 | unsigned long expires; | ||
86 | struct list_head next; | ||
87 | }; | ||
88 | |||
74 | /** | 89 | /** |
75 | * publ_to_item - add publication info to a publication message | 90 | * publ_to_item - add publication info to a publication message |
76 | */ | 91 | */ |
@@ -299,6 +314,52 @@ struct publication *tipc_update_nametbl(struct distr_item *i, u32 node, | |||
299 | } | 314 | } |
300 | 315 | ||
301 | /** | 316 | /** |
317 | * tipc_named_add_backlog - add a failed name table update to the backlog | ||
318 | * | ||
319 | */ | ||
320 | static void tipc_named_add_backlog(struct distr_item *i, u32 type, u32 node) | ||
321 | { | ||
322 | struct distr_queue_item *e; | ||
323 | unsigned long now = get_jiffies_64(); | ||
324 | |||
325 | e = kzalloc(sizeof(*e), GFP_ATOMIC); | ||
326 | if (!e) | ||
327 | return; | ||
328 | e->dtype = type; | ||
329 | e->node = node; | ||
330 | e->expires = now + msecs_to_jiffies(sysctl_tipc_named_timeout); | ||
331 | memcpy(e, i, sizeof(*i)); | ||
332 | list_add_tail(&e->next, &tipc_dist_queue); | ||
333 | } | ||
334 | |||
335 | /** | ||
336 | * tipc_named_process_backlog - try to process any pending name table updates | ||
337 | * from the network. | ||
338 | */ | ||
339 | void tipc_named_process_backlog(void) | ||
340 | { | ||
341 | struct distr_queue_item *e, *tmp; | ||
342 | char addr[16]; | ||
343 | unsigned long now = get_jiffies_64(); | ||
344 | |||
345 | list_for_each_entry_safe(e, tmp, &tipc_dist_queue, next) { | ||
346 | if (time_after(e->expires, now)) { | ||
347 | if (!tipc_update_nametbl(&e->i, e->node, e->dtype)) | ||
348 | continue; | ||
349 | } else { | ||
350 | tipc_addr_string_fill(addr, e->node); | ||
351 | pr_warn_ratelimited("Dropping name table update (%d) of {%u, %u, %u} from %s key=%u\n", | ||
352 | e->dtype, ntohl(e->i.type), | ||
353 | ntohl(e->i.lower), | ||
354 | ntohl(e->i.upper), | ||
355 | addr, ntohl(e->i.key)); | ||
356 | } | ||
357 | list_del(&e->next); | ||
358 | kfree(e); | ||
359 | } | ||
360 | } | ||
361 | |||
362 | /** | ||
302 | * tipc_named_rcv - process name table update message sent by another node | 363 | * tipc_named_rcv - process name table update message sent by another node |
303 | */ | 364 | */ |
304 | void tipc_named_rcv(struct sk_buff *buf) | 365 | void tipc_named_rcv(struct sk_buff *buf) |
@@ -306,13 +367,15 @@ void tipc_named_rcv(struct sk_buff *buf) | |||
306 | struct tipc_msg *msg = buf_msg(buf); | 367 | struct tipc_msg *msg = buf_msg(buf); |
307 | struct distr_item *item = (struct distr_item *)msg_data(msg); | 368 | struct distr_item *item = (struct distr_item *)msg_data(msg); |
308 | u32 count = msg_data_sz(msg) / ITEM_SIZE; | 369 | u32 count = msg_data_sz(msg) / ITEM_SIZE; |
370 | u32 node = msg_orignode(msg); | ||
309 | 371 | ||
310 | write_lock_bh(&tipc_nametbl_lock); | 372 | write_lock_bh(&tipc_nametbl_lock); |
311 | while (count--) { | 373 | while (count--) { |
312 | tipc_update_nametbl(item, msg_orignode(msg), | 374 | if (!tipc_update_nametbl(item, node, msg_type(msg))) |
313 | msg_type(msg)); | 375 | tipc_named_add_backlog(item, msg_type(msg), node); |
314 | item++; | 376 | item++; |
315 | } | 377 | } |
378 | tipc_named_process_backlog(); | ||
316 | write_unlock_bh(&tipc_nametbl_lock); | 379 | write_unlock_bh(&tipc_nametbl_lock); |
317 | kfree_skb(buf); | 380 | kfree_skb(buf); |
318 | } | 381 | } |
diff --git a/net/tipc/name_distr.h b/net/tipc/name_distr.h index 8afe32b7fc9a..b9e75feb3434 100644 --- a/net/tipc/name_distr.h +++ b/net/tipc/name_distr.h | |||
@@ -73,5 +73,6 @@ void named_cluster_distribute(struct sk_buff *buf); | |||
73 | void tipc_named_node_up(u32 dnode); | 73 | void tipc_named_node_up(u32 dnode); |
74 | void tipc_named_rcv(struct sk_buff *buf); | 74 | void tipc_named_rcv(struct sk_buff *buf); |
75 | void tipc_named_reinit(void); | 75 | void tipc_named_reinit(void); |
76 | void tipc_named_process_backlog(void); | ||
76 | 77 | ||
77 | #endif | 78 | #endif |
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index c058e30f84aa..3a6a0a7c0759 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c | |||
@@ -261,8 +261,6 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, | |||
261 | 261 | ||
262 | /* Lower end overlaps existing entry => need an exact match */ | 262 | /* Lower end overlaps existing entry => need an exact match */ |
263 | if ((sseq->lower != lower) || (sseq->upper != upper)) { | 263 | if ((sseq->lower != lower) || (sseq->upper != upper)) { |
264 | pr_warn("Cannot publish {%u,%u,%u}, overlap error\n", | ||
265 | type, lower, upper); | ||
266 | return NULL; | 264 | return NULL; |
267 | } | 265 | } |
268 | 266 | ||
@@ -284,8 +282,6 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, | |||
284 | /* Fail if upper end overlaps into an existing entry */ | 282 | /* Fail if upper end overlaps into an existing entry */ |
285 | if ((inspos < nseq->first_free) && | 283 | if ((inspos < nseq->first_free) && |
286 | (upper >= nseq->sseqs[inspos].lower)) { | 284 | (upper >= nseq->sseqs[inspos].lower)) { |
287 | pr_warn("Cannot publish {%u,%u,%u}, overlap error\n", | ||
288 | type, lower, upper); | ||
289 | return NULL; | 285 | return NULL; |
290 | } | 286 | } |
291 | 287 | ||
@@ -677,6 +673,8 @@ struct publication *tipc_nametbl_publish(u32 type, u32 lower, u32 upper, | |||
677 | if (likely(publ)) { | 673 | if (likely(publ)) { |
678 | table.local_publ_count++; | 674 | table.local_publ_count++; |
679 | buf = tipc_named_publish(publ); | 675 | buf = tipc_named_publish(publ); |
676 | /* Any pending external events? */ | ||
677 | tipc_named_process_backlog(); | ||
680 | } | 678 | } |
681 | write_unlock_bh(&tipc_nametbl_lock); | 679 | write_unlock_bh(&tipc_nametbl_lock); |
682 | 680 | ||
@@ -698,6 +696,8 @@ int tipc_nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key) | |||
698 | if (likely(publ)) { | 696 | if (likely(publ)) { |
699 | table.local_publ_count--; | 697 | table.local_publ_count--; |
700 | buf = tipc_named_withdraw(publ); | 698 | buf = tipc_named_withdraw(publ); |
699 | /* Any pending external events? */ | ||
700 | tipc_named_process_backlog(); | ||
701 | write_unlock_bh(&tipc_nametbl_lock); | 701 | write_unlock_bh(&tipc_nametbl_lock); |
702 | list_del_init(&publ->pport_list); | 702 | list_del_init(&publ->pport_list); |
703 | kfree(publ); | 703 | kfree(publ); |
diff --git a/net/tipc/sysctl.c b/net/tipc/sysctl.c index f3fef93325a8..1a779b1e8510 100644 --- a/net/tipc/sysctl.c +++ b/net/tipc/sysctl.c | |||
@@ -47,6 +47,13 @@ static struct ctl_table tipc_table[] = { | |||
47 | .mode = 0644, | 47 | .mode = 0644, |
48 | .proc_handler = proc_dointvec, | 48 | .proc_handler = proc_dointvec, |
49 | }, | 49 | }, |
50 | { | ||
51 | .procname = "named_timeout", | ||
52 | .data = &sysctl_tipc_named_timeout, | ||
53 | .maxlen = sizeof(sysctl_tipc_named_timeout), | ||
54 | .mode = 0644, | ||
55 | .proc_handler = proc_dointvec, | ||
56 | }, | ||
50 | {} | 57 | {} |
51 | }; | 58 | }; |
52 | 59 | ||