diff options
author | Allan Stephens <allan.stephens@windriver.com> | 2011-05-30 09:44:38 -0400 |
---|---|---|
committer | Paul Gortmaker <paul.gortmaker@windriver.com> | 2011-06-24 16:18:16 -0400 |
commit | b52124a50fa7b870a3d1a18a8ff56273c7d690dd (patch) | |
tree | 8f8de3584f1383125cecc60efb67734e2b585945 /net/tipc/name_table.c | |
parent | 7eb878ed8e0eae67269439bfd82234f9ba52ffe4 (diff) |
tipc: Partition name table instance array info into two parts
Modifies the name table array structure that contains the name
sequence instances for a given name type so that the publication
lists associated with a given instance are stored in a dynamically
allocated structure, rather than being embedded within the array
entry itself. This change is being done for several reasons:
1) It reduces the amount of data that needs to be copied whenever
a given array is expanded or contracted to accommodate the first
publication of a new name sequence or the removal of the last
publication of an existing name sequence.
2) It reduces the amount of memory associated with array entries that
are currently unused.
3) It facilitates the upcoming conversion of the publication lists
from TIPC-specific circular lists to standard kernel lists. (Standard
lists cannot be used with the former array structure because the
relocation of array entries during array expansion and contraction
would corrupt the lists.)
Note that, aside from introducing a small amount of code to dynamically
allocate and free the structure that now holds publication list info,
this change is largely a simple renaming exercise that replaces
references to "sseq->LIST" with "sseq->info->LIST" (or "info->LIST").
Signed-off-by: Allan Stephens <allan.stephens@windriver.com>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
Diffstat (limited to 'net/tipc/name_table.c')
-rw-r--r-- | net/tipc/name_table.c | 150 |
1 files changed, 89 insertions, 61 deletions
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index 205ed4a4e186..9cd58f8318f1 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c | |||
@@ -44,9 +44,7 @@ | |||
44 | static int tipc_nametbl_size = 1024; /* must be a power of 2 */ | 44 | static int tipc_nametbl_size = 1024; /* must be a power of 2 */ |
45 | 45 | ||
46 | /** | 46 | /** |
47 | * struct sub_seq - container for all published instances of a name sequence | 47 | * struct name_info - name sequence publication info |
48 | * @lower: name sequence lower bound | ||
49 | * @upper: name sequence upper bound | ||
50 | * @node_list: circular list of publications made by own node | 48 | * @node_list: circular list of publications made by own node |
51 | * @cluster_list: circular list of publications made by own cluster | 49 | * @cluster_list: circular list of publications made by own cluster |
52 | * @zone_list: circular list of publications made by own zone | 50 | * @zone_list: circular list of publications made by own zone |
@@ -59,9 +57,7 @@ static int tipc_nametbl_size = 1024; /* must be a power of 2 */ | |||
59 | * (The cluster and node lists may be empty.) | 57 | * (The cluster and node lists may be empty.) |
60 | */ | 58 | */ |
61 | 59 | ||
62 | struct sub_seq { | 60 | struct name_info { |
63 | u32 lower; | ||
64 | u32 upper; | ||
65 | struct publication *node_list; | 61 | struct publication *node_list; |
66 | struct publication *cluster_list; | 62 | struct publication *cluster_list; |
67 | struct publication *zone_list; | 63 | struct publication *zone_list; |
@@ -71,6 +67,19 @@ struct sub_seq { | |||
71 | }; | 67 | }; |
72 | 68 | ||
73 | /** | 69 | /** |
70 | * struct sub_seq - container for all published instances of a name sequence | ||
71 | * @lower: name sequence lower bound | ||
72 | * @upper: name sequence upper bound | ||
73 | * @info: pointer to name sequence publication info | ||
74 | */ | ||
75 | |||
76 | struct sub_seq { | ||
77 | u32 lower; | ||
78 | u32 upper; | ||
79 | struct name_info *info; | ||
80 | }; | ||
81 | |||
82 | /** | ||
74 | * struct name_seq - container for all published instances of a name type | 83 | * struct name_seq - container for all published instances of a name type |
75 | * @type: 32 bit 'type' value for name sequence | 84 | * @type: 32 bit 'type' value for name sequence |
76 | * @sseq: pointer to dynamically-sized array of sub-sequences of this 'type'; | 85 | * @sseq: pointer to dynamically-sized array of sub-sequences of this 'type'; |
@@ -246,6 +255,7 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, | |||
246 | struct subscription *st; | 255 | struct subscription *st; |
247 | struct publication *publ; | 256 | struct publication *publ; |
248 | struct sub_seq *sseq; | 257 | struct sub_seq *sseq; |
258 | struct name_info *info; | ||
249 | int created_subseq = 0; | 259 | int created_subseq = 0; |
250 | 260 | ||
251 | sseq = nameseq_find_subseq(nseq, lower); | 261 | sseq = nameseq_find_subseq(nseq, lower); |
@@ -258,6 +268,8 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, | |||
258 | type, lower, upper); | 268 | type, lower, upper); |
259 | return NULL; | 269 | return NULL; |
260 | } | 270 | } |
271 | |||
272 | info = sseq->info; | ||
261 | } else { | 273 | } else { |
262 | u32 inspos; | 274 | u32 inspos; |
263 | struct sub_seq *freesseq; | 275 | struct sub_seq *freesseq; |
@@ -292,6 +304,13 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, | |||
292 | nseq->alloc *= 2; | 304 | nseq->alloc *= 2; |
293 | } | 305 | } |
294 | 306 | ||
307 | info = kzalloc(sizeof(*info), GFP_ATOMIC); | ||
308 | if (!info) { | ||
309 | warn("Cannot publish {%u,%u,%u}, no memory\n", | ||
310 | type, lower, upper); | ||
311 | return NULL; | ||
312 | } | ||
313 | |||
295 | /* Insert new sub-sequence */ | 314 | /* Insert new sub-sequence */ |
296 | 315 | ||
297 | sseq = &nseq->sseqs[inspos]; | 316 | sseq = &nseq->sseqs[inspos]; |
@@ -301,6 +320,7 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, | |||
301 | nseq->first_free++; | 320 | nseq->first_free++; |
302 | sseq->lower = lower; | 321 | sseq->lower = lower; |
303 | sseq->upper = upper; | 322 | sseq->upper = upper; |
323 | sseq->info = info; | ||
304 | created_subseq = 1; | 324 | created_subseq = 1; |
305 | } | 325 | } |
306 | 326 | ||
@@ -310,32 +330,32 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, | |||
310 | if (!publ) | 330 | if (!publ) |
311 | return NULL; | 331 | return NULL; |
312 | 332 | ||
313 | sseq->zone_list_size++; | 333 | info->zone_list_size++; |
314 | if (!sseq->zone_list) | 334 | if (!info->zone_list) |
315 | sseq->zone_list = publ->zone_list_next = publ; | 335 | info->zone_list = publ->zone_list_next = publ; |
316 | else { | 336 | else { |
317 | publ->zone_list_next = sseq->zone_list->zone_list_next; | 337 | publ->zone_list_next = info->zone_list->zone_list_next; |
318 | sseq->zone_list->zone_list_next = publ; | 338 | info->zone_list->zone_list_next = publ; |
319 | } | 339 | } |
320 | 340 | ||
321 | if (in_own_cluster(node)) { | 341 | if (in_own_cluster(node)) { |
322 | sseq->cluster_list_size++; | 342 | info->cluster_list_size++; |
323 | if (!sseq->cluster_list) | 343 | if (!info->cluster_list) |
324 | sseq->cluster_list = publ->cluster_list_next = publ; | 344 | info->cluster_list = publ->cluster_list_next = publ; |
325 | else { | 345 | else { |
326 | publ->cluster_list_next = | 346 | publ->cluster_list_next = |
327 | sseq->cluster_list->cluster_list_next; | 347 | info->cluster_list->cluster_list_next; |
328 | sseq->cluster_list->cluster_list_next = publ; | 348 | info->cluster_list->cluster_list_next = publ; |
329 | } | 349 | } |
330 | } | 350 | } |
331 | 351 | ||
332 | if (node == tipc_own_addr) { | 352 | if (node == tipc_own_addr) { |
333 | sseq->node_list_size++; | 353 | info->node_list_size++; |
334 | if (!sseq->node_list) | 354 | if (!info->node_list) |
335 | sseq->node_list = publ->node_list_next = publ; | 355 | info->node_list = publ->node_list_next = publ; |
336 | else { | 356 | else { |
337 | publ->node_list_next = sseq->node_list->node_list_next; | 357 | publ->node_list_next = info->node_list->node_list_next; |
338 | sseq->node_list->node_list_next = publ; | 358 | info->node_list->node_list_next = publ; |
339 | } | 359 | } |
340 | } | 360 | } |
341 | 361 | ||
@@ -373,6 +393,7 @@ static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 i | |||
373 | struct publication *curr; | 393 | struct publication *curr; |
374 | struct publication *prev; | 394 | struct publication *prev; |
375 | struct sub_seq *sseq = nameseq_find_subseq(nseq, inst); | 395 | struct sub_seq *sseq = nameseq_find_subseq(nseq, inst); |
396 | struct name_info *info; | ||
376 | struct sub_seq *free; | 397 | struct sub_seq *free; |
377 | struct subscription *s, *st; | 398 | struct subscription *s, *st; |
378 | int removed_subseq = 0; | 399 | int removed_subseq = 0; |
@@ -380,40 +401,42 @@ static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 i | |||
380 | if (!sseq) | 401 | if (!sseq) |
381 | return NULL; | 402 | return NULL; |
382 | 403 | ||
404 | info = sseq->info; | ||
405 | |||
383 | /* Remove publication from zone scope list */ | 406 | /* Remove publication from zone scope list */ |
384 | 407 | ||
385 | prev = sseq->zone_list; | 408 | prev = info->zone_list; |
386 | publ = sseq->zone_list->zone_list_next; | 409 | publ = info->zone_list->zone_list_next; |
387 | while ((publ->key != key) || (publ->ref != ref) || | 410 | while ((publ->key != key) || (publ->ref != ref) || |
388 | (publ->node && (publ->node != node))) { | 411 | (publ->node && (publ->node != node))) { |
389 | prev = publ; | 412 | prev = publ; |
390 | publ = publ->zone_list_next; | 413 | publ = publ->zone_list_next; |
391 | if (prev == sseq->zone_list) { | 414 | if (prev == info->zone_list) { |
392 | 415 | ||
393 | /* Prevent endless loop if publication not found */ | 416 | /* Prevent endless loop if publication not found */ |
394 | 417 | ||
395 | return NULL; | 418 | return NULL; |
396 | } | 419 | } |
397 | } | 420 | } |
398 | if (publ != sseq->zone_list) | 421 | if (publ != info->zone_list) |
399 | prev->zone_list_next = publ->zone_list_next; | 422 | prev->zone_list_next = publ->zone_list_next; |
400 | else if (publ->zone_list_next != publ) { | 423 | else if (publ->zone_list_next != publ) { |
401 | prev->zone_list_next = publ->zone_list_next; | 424 | prev->zone_list_next = publ->zone_list_next; |
402 | sseq->zone_list = publ->zone_list_next; | 425 | info->zone_list = publ->zone_list_next; |
403 | } else { | 426 | } else { |
404 | sseq->zone_list = NULL; | 427 | info->zone_list = NULL; |
405 | } | 428 | } |
406 | sseq->zone_list_size--; | 429 | info->zone_list_size--; |
407 | 430 | ||
408 | /* Remove publication from cluster scope list, if present */ | 431 | /* Remove publication from cluster scope list, if present */ |
409 | 432 | ||
410 | if (in_own_cluster(node)) { | 433 | if (in_own_cluster(node)) { |
411 | prev = sseq->cluster_list; | 434 | prev = info->cluster_list; |
412 | curr = sseq->cluster_list->cluster_list_next; | 435 | curr = info->cluster_list->cluster_list_next; |
413 | while (curr != publ) { | 436 | while (curr != publ) { |
414 | prev = curr; | 437 | prev = curr; |
415 | curr = curr->cluster_list_next; | 438 | curr = curr->cluster_list_next; |
416 | if (prev == sseq->cluster_list) { | 439 | if (prev == info->cluster_list) { |
417 | 440 | ||
418 | /* Prevent endless loop for malformed list */ | 441 | /* Prevent endless loop for malformed list */ |
419 | 442 | ||
@@ -424,27 +447,27 @@ static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 i | |||
424 | goto end_cluster; | 447 | goto end_cluster; |
425 | } | 448 | } |
426 | } | 449 | } |
427 | if (publ != sseq->cluster_list) | 450 | if (publ != info->cluster_list) |
428 | prev->cluster_list_next = publ->cluster_list_next; | 451 | prev->cluster_list_next = publ->cluster_list_next; |
429 | else if (publ->cluster_list_next != publ) { | 452 | else if (publ->cluster_list_next != publ) { |
430 | prev->cluster_list_next = publ->cluster_list_next; | 453 | prev->cluster_list_next = publ->cluster_list_next; |
431 | sseq->cluster_list = publ->cluster_list_next; | 454 | info->cluster_list = publ->cluster_list_next; |
432 | } else { | 455 | } else { |
433 | sseq->cluster_list = NULL; | 456 | info->cluster_list = NULL; |
434 | } | 457 | } |
435 | sseq->cluster_list_size--; | 458 | info->cluster_list_size--; |
436 | } | 459 | } |
437 | end_cluster: | 460 | end_cluster: |
438 | 461 | ||
439 | /* Remove publication from node scope list, if present */ | 462 | /* Remove publication from node scope list, if present */ |
440 | 463 | ||
441 | if (node == tipc_own_addr) { | 464 | if (node == tipc_own_addr) { |
442 | prev = sseq->node_list; | 465 | prev = info->node_list; |
443 | curr = sseq->node_list->node_list_next; | 466 | curr = info->node_list->node_list_next; |
444 | while (curr != publ) { | 467 | while (curr != publ) { |
445 | prev = curr; | 468 | prev = curr; |
446 | curr = curr->node_list_next; | 469 | curr = curr->node_list_next; |
447 | if (prev == sseq->node_list) { | 470 | if (prev == info->node_list) { |
448 | 471 | ||
449 | /* Prevent endless loop for malformed list */ | 472 | /* Prevent endless loop for malformed list */ |
450 | 473 | ||
@@ -455,21 +478,22 @@ end_cluster: | |||
455 | goto end_node; | 478 | goto end_node; |
456 | } | 479 | } |
457 | } | 480 | } |
458 | if (publ != sseq->node_list) | 481 | if (publ != info->node_list) |
459 | prev->node_list_next = publ->node_list_next; | 482 | prev->node_list_next = publ->node_list_next; |
460 | else if (publ->node_list_next != publ) { | 483 | else if (publ->node_list_next != publ) { |
461 | prev->node_list_next = publ->node_list_next; | 484 | prev->node_list_next = publ->node_list_next; |
462 | sseq->node_list = publ->node_list_next; | 485 | info->node_list = publ->node_list_next; |
463 | } else { | 486 | } else { |
464 | sseq->node_list = NULL; | 487 | info->node_list = NULL; |
465 | } | 488 | } |
466 | sseq->node_list_size--; | 489 | info->node_list_size--; |
467 | } | 490 | } |
468 | end_node: | 491 | end_node: |
469 | 492 | ||
470 | /* Contract subseq list if no more publications for that subseq */ | 493 | /* Contract subseq list if no more publications for that subseq */ |
471 | 494 | ||
472 | if (!sseq->zone_list) { | 495 | if (!info->zone_list) { |
496 | kfree(info); | ||
473 | free = &nseq->sseqs[nseq->first_free--]; | 497 | free = &nseq->sseqs[nseq->first_free--]; |
474 | memmove(sseq, sseq + 1, (free - (sseq + 1)) * sizeof(*sseq)); | 498 | memmove(sseq, sseq + 1, (free - (sseq + 1)) * sizeof(*sseq)); |
475 | removed_subseq = 1; | 499 | removed_subseq = 1; |
@@ -506,7 +530,7 @@ static void tipc_nameseq_subscribe(struct name_seq *nseq, struct subscription *s | |||
506 | return; | 530 | return; |
507 | 531 | ||
508 | while (sseq != &nseq->sseqs[nseq->first_free]) { | 532 | while (sseq != &nseq->sseqs[nseq->first_free]) { |
509 | struct publication *zl = sseq->zone_list; | 533 | struct publication *zl = sseq->info->zone_list; |
510 | if (zl && tipc_subscr_overlap(s, sseq->lower, sseq->upper)) { | 534 | if (zl && tipc_subscr_overlap(s, sseq->lower, sseq->upper)) { |
511 | struct publication *crs = zl; | 535 | struct publication *crs = zl; |
512 | int must_report = 1; | 536 | int must_report = 1; |
@@ -591,6 +615,7 @@ struct publication *tipc_nametbl_remove_publ(u32 type, u32 lower, | |||
591 | u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *destnode) | 615 | u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *destnode) |
592 | { | 616 | { |
593 | struct sub_seq *sseq; | 617 | struct sub_seq *sseq; |
618 | struct name_info *info; | ||
594 | struct publication *publ = NULL; | 619 | struct publication *publ = NULL; |
595 | struct name_seq *seq; | 620 | struct name_seq *seq; |
596 | u32 ref; | 621 | u32 ref; |
@@ -606,12 +631,13 @@ u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *destnode) | |||
606 | if (unlikely(!sseq)) | 631 | if (unlikely(!sseq)) |
607 | goto not_found; | 632 | goto not_found; |
608 | spin_lock_bh(&seq->lock); | 633 | spin_lock_bh(&seq->lock); |
634 | info = sseq->info; | ||
609 | 635 | ||
610 | /* Closest-First Algorithm: */ | 636 | /* Closest-First Algorithm: */ |
611 | if (likely(!*destnode)) { | 637 | if (likely(!*destnode)) { |
612 | publ = sseq->node_list; | 638 | publ = info->node_list; |
613 | if (publ) { | 639 | if (publ) { |
614 | sseq->node_list = publ->node_list_next; | 640 | info->node_list = publ->node_list_next; |
615 | found: | 641 | found: |
616 | ref = publ->ref; | 642 | ref = publ->ref; |
617 | *destnode = publ->node; | 643 | *destnode = publ->node; |
@@ -619,35 +645,35 @@ found: | |||
619 | read_unlock_bh(&tipc_nametbl_lock); | 645 | read_unlock_bh(&tipc_nametbl_lock); |
620 | return ref; | 646 | return ref; |
621 | } | 647 | } |
622 | publ = sseq->cluster_list; | 648 | publ = info->cluster_list; |
623 | if (publ) { | 649 | if (publ) { |
624 | sseq->cluster_list = publ->cluster_list_next; | 650 | info->cluster_list = publ->cluster_list_next; |
625 | goto found; | 651 | goto found; |
626 | } | 652 | } |
627 | publ = sseq->zone_list; | 653 | publ = info->zone_list; |
628 | if (publ) { | 654 | if (publ) { |
629 | sseq->zone_list = publ->zone_list_next; | 655 | info->zone_list = publ->zone_list_next; |
630 | goto found; | 656 | goto found; |
631 | } | 657 | } |
632 | } | 658 | } |
633 | 659 | ||
634 | /* Round-Robin Algorithm: */ | 660 | /* Round-Robin Algorithm: */ |
635 | else if (*destnode == tipc_own_addr) { | 661 | else if (*destnode == tipc_own_addr) { |
636 | publ = sseq->node_list; | 662 | publ = info->node_list; |
637 | if (publ) { | 663 | if (publ) { |
638 | sseq->node_list = publ->node_list_next; | 664 | info->node_list = publ->node_list_next; |
639 | goto found; | 665 | goto found; |
640 | } | 666 | } |
641 | } else if (in_own_cluster(*destnode)) { | 667 | } else if (in_own_cluster(*destnode)) { |
642 | publ = sseq->cluster_list; | 668 | publ = info->cluster_list; |
643 | if (publ) { | 669 | if (publ) { |
644 | sseq->cluster_list = publ->cluster_list_next; | 670 | info->cluster_list = publ->cluster_list_next; |
645 | goto found; | 671 | goto found; |
646 | } | 672 | } |
647 | } else { | 673 | } else { |
648 | publ = sseq->zone_list; | 674 | publ = info->zone_list; |
649 | if (publ) { | 675 | if (publ) { |
650 | sseq->zone_list = publ->zone_list_next; | 676 | info->zone_list = publ->zone_list_next; |
651 | goto found; | 677 | goto found; |
652 | } | 678 | } |
653 | } | 679 | } |
@@ -676,6 +702,7 @@ int tipc_nametbl_mc_translate(u32 type, u32 lower, u32 upper, u32 limit, | |||
676 | struct name_seq *seq; | 702 | struct name_seq *seq; |
677 | struct sub_seq *sseq; | 703 | struct sub_seq *sseq; |
678 | struct sub_seq *sseq_stop; | 704 | struct sub_seq *sseq_stop; |
705 | struct name_info *info; | ||
679 | int res = 0; | 706 | int res = 0; |
680 | 707 | ||
681 | read_lock_bh(&tipc_nametbl_lock); | 708 | read_lock_bh(&tipc_nametbl_lock); |
@@ -693,16 +720,17 @@ int tipc_nametbl_mc_translate(u32 type, u32 lower, u32 upper, u32 limit, | |||
693 | if (sseq->lower > upper) | 720 | if (sseq->lower > upper) |
694 | break; | 721 | break; |
695 | 722 | ||
696 | publ = sseq->node_list; | 723 | info = sseq->info; |
724 | publ = info->node_list; | ||
697 | if (publ) { | 725 | if (publ) { |
698 | do { | 726 | do { |
699 | if (publ->scope <= limit) | 727 | if (publ->scope <= limit) |
700 | tipc_port_list_add(dports, publ->ref); | 728 | tipc_port_list_add(dports, publ->ref); |
701 | publ = publ->node_list_next; | 729 | publ = publ->node_list_next; |
702 | } while (publ != sseq->node_list); | 730 | } while (publ != info->node_list); |
703 | } | 731 | } |
704 | 732 | ||
705 | if (sseq->cluster_list_size != sseq->node_list_size) | 733 | if (info->cluster_list_size != info->node_list_size) |
706 | res = 1; | 734 | res = 1; |
707 | } | 735 | } |
708 | 736 | ||
@@ -840,7 +868,7 @@ static void subseq_list(struct sub_seq *sseq, struct print_buf *buf, u32 depth, | |||
840 | { | 868 | { |
841 | char portIdStr[27]; | 869 | char portIdStr[27]; |
842 | const char *scope_str[] = {"", " zone", " cluster", " node"}; | 870 | const char *scope_str[] = {"", " zone", " cluster", " node"}; |
843 | struct publication *publ = sseq->zone_list; | 871 | struct publication *publ = sseq->info->zone_list; |
844 | 872 | ||
845 | tipc_printf(buf, "%-10u %-10u ", sseq->lower, sseq->upper); | 873 | tipc_printf(buf, "%-10u %-10u ", sseq->lower, sseq->upper); |
846 | 874 | ||
@@ -860,7 +888,7 @@ static void subseq_list(struct sub_seq *sseq, struct print_buf *buf, u32 depth, | |||
860 | } | 888 | } |
861 | 889 | ||
862 | publ = publ->zone_list_next; | 890 | publ = publ->zone_list_next; |
863 | if (publ == sseq->zone_list) | 891 | if (publ == sseq->info->zone_list) |
864 | break; | 892 | break; |
865 | 893 | ||
866 | tipc_printf(buf, "\n%33s", " "); | 894 | tipc_printf(buf, "\n%33s", " "); |