Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tipc: Optimization to multicast name lookup algorithm

This patch simplifies and speeds up TIPC's algorithm for identifying
on-node and off-node destinations that overlap a multicast name
sequence range. Rather than traversing the list of all known name
publications within the cluster, it now traverses the (potentially
much shorter) list of name publications made by the node itself, and
determines if any off-node destinations exist by comparing the sizes
of the two lists. (Since the node list must be a subset of the
cluster list, a difference in sizes means that at least one off-node
destination must exist.)

Signed-off-by: Allan Stephens <allan.stephens@windriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Allan Stephens and committed by
David S. Miller
968edbe1 1aad72d6

+30 -13
+30 -13
net/tipc/name_table.c
··· 2 2 * net/tipc/name_table.c: TIPC name table code 3 3 * 4 4 * Copyright (c) 2000-2006, Ericsson AB 5 - * Copyright (c) 2004-2005, Wind River Systems 5 + * Copyright (c) 2004-2008, Wind River Systems 6 6 * All rights reserved. 7 7 * 8 8 * Redistribution and use in source and binary forms, with or without ··· 52 52 * struct sub_seq - container for all published instances of a name sequence 53 53 * @lower: name sequence lower bound 54 54 * @upper: name sequence upper bound 55 - * @node_list: circular list of matching publications with >= node scope 56 - * @cluster_list: circular list of matching publications with >= cluster scope 57 - * @zone_list: circular list of matching publications with >= zone scope 55 + * @node_list: circular list of publications made by own node 56 + * @cluster_list: circular list of publications made by own cluster 57 + * @zone_list: circular list of publications made by own zone 58 + * @node_list_size: number of entries in "node_list" 59 + * @cluster_list_size: number of entries in "cluster_list" 60 + * @zone_list_size: number of entries in "zone_list" 61 + * 62 + * Note: The zone list always contains at least one entry, since all 63 + * publications of the associated name sequence belong to it. 64 + * (The cluster and node lists may be empty.) 58 65 */ 59 66 60 67 struct sub_seq { ··· 70 63 struct publication *node_list; 71 64 struct publication *cluster_list; 72 65 struct publication *zone_list; 66 + u32 node_list_size; 67 + u32 cluster_list_size; 68 + u32 zone_list_size; 73 69 }; 74 70 75 71 /** ··· 327 317 dbg("inserting publ %p, node=0x%x publ->node=0x%x, subscr->node=%p\n", 328 318 publ, node, publ->node, publ->subscr.node); 329 319 320 + sseq->zone_list_size++; 330 321 if (!sseq->zone_list) 331 322 sseq->zone_list = publ->zone_list_next = publ; 332 323 else { ··· 336 325 } 337 326 338 327 if (in_own_cluster(node)) { 328 + sseq->cluster_list_size++; 339 329 if (!sseq->cluster_list) 340 330 sseq->cluster_list = publ->cluster_list_next = publ; 341 331 else { ··· 347 335 } 348 336 349 337 if (node == tipc_own_addr) { 338 + sseq->node_list_size++; 350 339 if (!sseq->node_list) 351 340 sseq->node_list = publ->node_list_next = publ; 352 341 else { ··· 424 411 } else { 425 412 sseq->zone_list = NULL; 426 413 } 414 + sseq->zone_list_size--; 427 415 428 416 /* Remove publication from cluster scope list, if present */ 429 417 ··· 453 439 } else { 454 440 sseq->cluster_list = NULL; 455 441 } 442 + sseq->cluster_list_size--; 456 443 } 457 444 end_cluster: 458 445 ··· 484 469 } else { 485 470 sseq->node_list = NULL; 486 471 } 472 + sseq->node_list_size--; 487 473 } 488 474 end_node: 489 475 ··· 725 709 726 710 if (sseq->lower > upper) 727 711 break; 728 - publ = sseq->cluster_list; 729 - if (publ) 712 + 713 + publ = sseq->node_list; 714 + if (publ) { 730 715 do { 731 - if (publ->scope > limit) 732 - /* ignore out-of-scope publication */ ; 733 - else if (publ->node == tipc_own_addr) 716 + if (publ->scope <= limit) 734 717 tipc_port_list_add(dports, publ->ref); 735 - else 736 - res = 1; 737 - publ = publ->cluster_list_next; 738 - } while (publ != sseq->cluster_list); 718 + publ = publ->node_list_next; 719 + } while (publ != sseq->node_list); 720 + } 721 + 722 + if (sseq->cluster_list_size != sseq->node_list_size) 723 + res = 1; 739 724 } 740 725 741 726 spin_unlock_bh(&seq->lock);