From b52124a50fa7b870a3d1a18a8ff56273c7d690dd Mon Sep 17 00:00:00 2001
From: Allan Stephens <allan.stephens@windriver.com>
Date: Mon, 30 May 2011 09:44:38 -0400
Subject: 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>
---
 net/tipc/name_table.c | 150 ++++++++++++++++++++++++++++++--------------------
 1 file changed, 89 insertions(+), 61 deletions(-)

(limited to 'net/tipc/name_table.c')

diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 205ed4a4e18..9cd58f8318f 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -44,9 +44,7 @@
 static int tipc_nametbl_size = 1024;		/* must be a power of 2 */
 
 /**
- * struct sub_seq - container for all published instances of a name sequence
- * @lower: name sequence lower bound
- * @upper: name sequence upper bound
+ * struct name_info - name sequence publication info
  * @node_list: circular list of publications made by own node
  * @cluster_list: circular list of publications made by own cluster
  * @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 */
  *       (The cluster and node lists may be empty.)
  */
 
-struct sub_seq {
-	u32 lower;
-	u32 upper;
+struct name_info {
 	struct publication *node_list;
 	struct publication *cluster_list;
 	struct publication *zone_list;
@@ -70,6 +66,19 @@ struct sub_seq {
 	u32 zone_list_size;
 };
 
+/**
+ * struct sub_seq - container for all published instances of a name sequence
+ * @lower: name sequence lower bound
+ * @upper: name sequence upper bound
+ * @info: pointer to name sequence publication info
+ */
+
+struct sub_seq {
+	u32 lower;
+	u32 upper;
+	struct name_info *info;
+};
+
 /**
  * struct name_seq - container for all published instances of a name type
  * @type: 32 bit 'type' value for name sequence
@@ -246,6 +255,7 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
 	struct subscription *st;
 	struct publication *publ;
 	struct sub_seq *sseq;
+	struct name_info *info;
 	int created_subseq = 0;
 
 	sseq = nameseq_find_subseq(nseq, lower);
@@ -258,6 +268,8 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
 			     type, lower, upper);
 			return NULL;
 		}
+
+		info = sseq->info;
 	} else {
 		u32 inspos;
 		struct sub_seq *freesseq;
@@ -292,6 +304,13 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
 			nseq->alloc *= 2;
 		}
 
+		info = kzalloc(sizeof(*info), GFP_ATOMIC);
+		if (!info) {
+			warn("Cannot publish {%u,%u,%u}, no memory\n",
+			     type, lower, upper);
+			return NULL;
+		}
+
 		/* Insert new sub-sequence */
 
 		sseq = &nseq->sseqs[inspos];
@@ -301,6 +320,7 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
 		nseq->first_free++;
 		sseq->lower = lower;
 		sseq->upper = upper;
+		sseq->info = info;
 		created_subseq = 1;
 	}
 
@@ -310,32 +330,32 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
 	if (!publ)
 		return NULL;
 
-	sseq->zone_list_size++;
-	if (!sseq->zone_list)
-		sseq->zone_list = publ->zone_list_next = publ;
+	info->zone_list_size++;
+	if (!info->zone_list)
+		info->zone_list = publ->zone_list_next = publ;
 	else {
-		publ->zone_list_next = sseq->zone_list->zone_list_next;
-		sseq->zone_list->zone_list_next = publ;
+		publ->zone_list_next = info->zone_list->zone_list_next;
+		info->zone_list->zone_list_next = publ;
 	}
 
 	if (in_own_cluster(node)) {
-		sseq->cluster_list_size++;
-		if (!sseq->cluster_list)
-			sseq->cluster_list = publ->cluster_list_next = publ;
+		info->cluster_list_size++;
+		if (!info->cluster_list)
+			info->cluster_list = publ->cluster_list_next = publ;
 		else {
 			publ->cluster_list_next =
-			sseq->cluster_list->cluster_list_next;
-			sseq->cluster_list->cluster_list_next = publ;
+			info->cluster_list->cluster_list_next;
+			info->cluster_list->cluster_list_next = publ;
 		}
 	}
 
 	if (node == tipc_own_addr) {
-		sseq->node_list_size++;
-		if (!sseq->node_list)
-			sseq->node_list = publ->node_list_next = publ;
+		info->node_list_size++;
+		if (!info->node_list)
+			info->node_list = publ->node_list_next = publ;
 		else {
-			publ->node_list_next = sseq->node_list->node_list_next;
-			sseq->node_list->node_list_next = publ;
+			publ->node_list_next = info->node_list->node_list_next;
+			info->node_list->node_list_next = publ;
 		}
 	}
 
@@ -373,6 +393,7 @@ static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 i
 	struct publication *curr;
 	struct publication *prev;
 	struct sub_seq *sseq = nameseq_find_subseq(nseq, inst);
+	struct name_info *info;
 	struct sub_seq *free;
 	struct subscription *s, *st;
 	int removed_subseq = 0;
@@ -380,40 +401,42 @@ static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 i
 	if (!sseq)
 		return NULL;
 
+	info = sseq->info;
+
 	/* Remove publication from zone scope list */
 
-	prev = sseq->zone_list;
-	publ = sseq->zone_list->zone_list_next;
+	prev = info->zone_list;
+	publ = info->zone_list->zone_list_next;
 	while ((publ->key != key) || (publ->ref != ref) ||
 	       (publ->node && (publ->node != node))) {
 		prev = publ;
 		publ = publ->zone_list_next;
-		if (prev == sseq->zone_list) {
+		if (prev == info->zone_list) {
 
 			/* Prevent endless loop if publication not found */
 
 			return NULL;
 		}
 	}
-	if (publ != sseq->zone_list)
+	if (publ != info->zone_list)
 		prev->zone_list_next = publ->zone_list_next;
 	else if (publ->zone_list_next != publ) {
 		prev->zone_list_next = publ->zone_list_next;
-		sseq->zone_list = publ->zone_list_next;
+		info->zone_list = publ->zone_list_next;
 	} else {
-		sseq->zone_list = NULL;
+		info->zone_list = NULL;
 	}
-	sseq->zone_list_size--;
+	info->zone_list_size--;
 
 	/* Remove publication from cluster scope list, if present */
 
 	if (in_own_cluster(node)) {
-		prev = sseq->cluster_list;
-		curr = sseq->cluster_list->cluster_list_next;
+		prev = info->cluster_list;
+		curr = info->cluster_list->cluster_list_next;
 		while (curr != publ) {
 			prev = curr;
 			curr = curr->cluster_list_next;
-			if (prev == sseq->cluster_list) {
+			if (prev == info->cluster_list) {
 
 				/* Prevent endless loop for malformed list */
 
@@ -424,27 +447,27 @@ static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 i
 				goto end_cluster;
 			}
 		}
-		if (publ != sseq->cluster_list)
+		if (publ != info->cluster_list)
 			prev->cluster_list_next = publ->cluster_list_next;
 		else if (publ->cluster_list_next != publ) {
 			prev->cluster_list_next = publ->cluster_list_next;
-			sseq->cluster_list = publ->cluster_list_next;
+			info->cluster_list = publ->cluster_list_next;
 		} else {
-			sseq->cluster_list = NULL;
+			info->cluster_list = NULL;
 		}
-		sseq->cluster_list_size--;
+		info->cluster_list_size--;
 	}
 end_cluster:
 
 	/* Remove publication from node scope list, if present */
 
 	if (node == tipc_own_addr) {
-		prev = sseq->node_list;
-		curr = sseq->node_list->node_list_next;
+		prev = info->node_list;
+		curr = info->node_list->node_list_next;
 		while (curr != publ) {
 			prev = curr;
 			curr = curr->node_list_next;
-			if (prev == sseq->node_list) {
+			if (prev == info->node_list) {
 
 				/* Prevent endless loop for malformed list */
 
@@ -455,21 +478,22 @@ end_cluster:
 				goto end_node;
 			}
 		}
-		if (publ != sseq->node_list)
+		if (publ != info->node_list)
 			prev->node_list_next = publ->node_list_next;
 		else if (publ->node_list_next != publ) {
 			prev->node_list_next = publ->node_list_next;
-			sseq->node_list = publ->node_list_next;
+			info->node_list = publ->node_list_next;
 		} else {
-			sseq->node_list = NULL;
+			info->node_list = NULL;
 		}
-		sseq->node_list_size--;
+		info->node_list_size--;
 	}
 end_node:
 
 	/* Contract subseq list if no more publications for that subseq */
 
-	if (!sseq->zone_list) {
+	if (!info->zone_list) {
+		kfree(info);
 		free = &nseq->sseqs[nseq->first_free--];
 		memmove(sseq, sseq + 1, (free - (sseq + 1)) * sizeof(*sseq));
 		removed_subseq = 1;
@@ -506,7 +530,7 @@ static void tipc_nameseq_subscribe(struct name_seq *nseq, struct subscription *s
 		return;
 
 	while (sseq != &nseq->sseqs[nseq->first_free]) {
-		struct publication *zl = sseq->zone_list;
+		struct publication *zl = sseq->info->zone_list;
 		if (zl && tipc_subscr_overlap(s, sseq->lower, sseq->upper)) {
 			struct publication *crs = zl;
 			int must_report = 1;
@@ -591,6 +615,7 @@ struct publication *tipc_nametbl_remove_publ(u32 type, u32 lower,
 u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *destnode)
 {
 	struct sub_seq *sseq;
+	struct name_info *info;
 	struct publication *publ = NULL;
 	struct name_seq *seq;
 	u32 ref;
@@ -606,12 +631,13 @@ u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *destnode)
 	if (unlikely(!sseq))
 		goto not_found;
 	spin_lock_bh(&seq->lock);
+	info = sseq->info;
 
 	/* Closest-First Algorithm: */
 	if (likely(!*destnode)) {
-		publ = sseq->node_list;
+		publ = info->node_list;
 		if (publ) {
-			sseq->node_list = publ->node_list_next;
+			info->node_list = publ->node_list_next;
 found:
 			ref = publ->ref;
 			*destnode = publ->node;
@@ -619,35 +645,35 @@ found:
 			read_unlock_bh(&tipc_nametbl_lock);
 			return ref;
 		}
-		publ = sseq->cluster_list;
+		publ = info->cluster_list;
 		if (publ) {
-			sseq->cluster_list = publ->cluster_list_next;
+			info->cluster_list = publ->cluster_list_next;
 			goto found;
 		}
-		publ = sseq->zone_list;
+		publ = info->zone_list;
 		if (publ) {
-			sseq->zone_list = publ->zone_list_next;
+			info->zone_list = publ->zone_list_next;
 			goto found;
 		}
 	}
 
 	/* Round-Robin Algorithm: */
 	else if (*destnode == tipc_own_addr) {
-		publ = sseq->node_list;
+		publ = info->node_list;
 		if (publ) {
-			sseq->node_list = publ->node_list_next;
+			info->node_list = publ->node_list_next;
 			goto found;
 		}
 	} else if (in_own_cluster(*destnode)) {
-		publ = sseq->cluster_list;
+		publ = info->cluster_list;
 		if (publ) {
-			sseq->cluster_list = publ->cluster_list_next;
+			info->cluster_list = publ->cluster_list_next;
 			goto found;
 		}
 	} else {
-		publ = sseq->zone_list;
+		publ = info->zone_list;
 		if (publ) {
-			sseq->zone_list = publ->zone_list_next;
+			info->zone_list = publ->zone_list_next;
 			goto found;
 		}
 	}
@@ -676,6 +702,7 @@ int tipc_nametbl_mc_translate(u32 type, u32 lower, u32 upper, u32 limit,
 	struct name_seq *seq;
 	struct sub_seq *sseq;
 	struct sub_seq *sseq_stop;
+	struct name_info *info;
 	int res = 0;
 
 	read_lock_bh(&tipc_nametbl_lock);
@@ -693,16 +720,17 @@ int tipc_nametbl_mc_translate(u32 type, u32 lower, u32 upper, u32 limit,
 		if (sseq->lower > upper)
 			break;
 
-		publ = sseq->node_list;
+		info = sseq->info;
+		publ = info->node_list;
 		if (publ) {
 			do {
 				if (publ->scope <= limit)
 					tipc_port_list_add(dports, publ->ref);
 				publ = publ->node_list_next;
-			} while (publ != sseq->node_list);
+			} while (publ != info->node_list);
 		}
 
-		if (sseq->cluster_list_size != sseq->node_list_size)
+		if (info->cluster_list_size != info->node_list_size)
 			res = 1;
 	}
 
@@ -840,7 +868,7 @@ static void subseq_list(struct sub_seq *sseq, struct print_buf *buf, u32 depth,
 {
 	char portIdStr[27];
 	const char *scope_str[] = {"", " zone", " cluster", " node"};
-	struct publication *publ = sseq->zone_list;
+	struct publication *publ = sseq->info->zone_list;
 
 	tipc_printf(buf, "%-10u %-10u ", sseq->lower, sseq->upper);
 
@@ -860,7 +888,7 @@ static void subseq_list(struct sub_seq *sseq, struct print_buf *buf, u32 depth,
 		}
 
 		publ = publ->zone_list_next;
-		if (publ == sseq->zone_list)
+		if (publ == sseq->info->zone_list)
 			break;
 
 		tipc_printf(buf, "\n%33s", " ");
-- 
cgit v1.2.3-70-g09d2


From f6f0a4d2d05f758f011a506731e84160d140304b Mon Sep 17 00:00:00 2001
From: Allan Stephens <allan.stephens@windriver.com>
Date: Mon, 30 May 2011 10:48:48 -0400
Subject: tipc: Convert name table publication lists to standard kernel lists

Modifies the main circular linked lists of publications used in TIPC's
name table to use the standard kernel linked list type. This change
simplifies the deletion of an existing publication by eliminating
the need to search up to three lists to locate the publication.
The use of standard list routines also helps improve the readability
of the name table code by make it clearer what each list operation
being performed is actually doing.

Signed-off-by: Allan Stephens <allan.stephens@windriver.com>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
---
 net/tipc/name_table.c | 240 +++++++++++++++++---------------------------------
 net/tipc/name_table.h |  14 +--
 2 files changed, 90 insertions(+), 164 deletions(-)

(limited to 'net/tipc/name_table.c')

diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 9cd58f8318f..7d85cc1ace0 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -2,7 +2,7 @@
  * net/tipc/name_table.c: TIPC name table code
  *
  * Copyright (c) 2000-2006, Ericsson AB
- * Copyright (c) 2004-2008, Wind River Systems
+ * Copyright (c) 2004-2008, 2010-2011, Wind River Systems
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -58,9 +58,9 @@ static int tipc_nametbl_size = 1024;		/* must be a power of 2 */
  */
 
 struct name_info {
-	struct publication *node_list;
-	struct publication *cluster_list;
-	struct publication *zone_list;
+	struct list_head node_list;
+	struct list_head cluster_list;
+	struct list_head zone_list;
 	u32 node_list_size;
 	u32 cluster_list_size;
 	u32 zone_list_size;
@@ -311,6 +311,10 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
 			return NULL;
 		}
 
+		INIT_LIST_HEAD(&info->node_list);
+		INIT_LIST_HEAD(&info->cluster_list);
+		INIT_LIST_HEAD(&info->zone_list);
+
 		/* Insert new sub-sequence */
 
 		sseq = &nseq->sseqs[inspos];
@@ -330,33 +334,17 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
 	if (!publ)
 		return NULL;
 
+	list_add(&publ->zone_list, &info->zone_list);
 	info->zone_list_size++;
-	if (!info->zone_list)
-		info->zone_list = publ->zone_list_next = publ;
-	else {
-		publ->zone_list_next = info->zone_list->zone_list_next;
-		info->zone_list->zone_list_next = publ;
-	}
 
 	if (in_own_cluster(node)) {
+		list_add(&publ->cluster_list, &info->cluster_list);
 		info->cluster_list_size++;
-		if (!info->cluster_list)
-			info->cluster_list = publ->cluster_list_next = publ;
-		else {
-			publ->cluster_list_next =
-			info->cluster_list->cluster_list_next;
-			info->cluster_list->cluster_list_next = publ;
-		}
 	}
 
 	if (node == tipc_own_addr) {
+		list_add(&publ->node_list, &info->node_list);
 		info->node_list_size++;
-		if (!info->node_list)
-			info->node_list = publ->node_list_next = publ;
-		else {
-			publ->node_list_next = info->node_list->node_list_next;
-			info->node_list->node_list_next = publ;
-		}
 	}
 
 	/*
@@ -390,8 +378,6 @@ static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 i
 						    u32 node, u32 ref, u32 key)
 {
 	struct publication *publ;
-	struct publication *curr;
-	struct publication *prev;
 	struct sub_seq *sseq = nameseq_find_subseq(nseq, inst);
 	struct name_info *info;
 	struct sub_seq *free;
@@ -403,96 +389,38 @@ static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 i
 
 	info = sseq->info;
 
-	/* Remove publication from zone scope list */
+	/* Locate publication, if it exists */
 
-	prev = info->zone_list;
-	publ = info->zone_list->zone_list_next;
-	while ((publ->key != key) || (publ->ref != ref) ||
-	       (publ->node && (publ->node != node))) {
-		prev = publ;
-		publ = publ->zone_list_next;
-		if (prev == info->zone_list) {
+	list_for_each_entry(publ, &info->zone_list, zone_list) {
+		if ((publ->key == key) && (publ->ref == ref) &&
+		    (!publ->node || (publ->node == node)))
+			goto found;
+	}
+	return NULL;
 
-			/* Prevent endless loop if publication not found */
+found:
+	/* Remove publication from zone scope list */
 
-			return NULL;
-		}
-	}
-	if (publ != info->zone_list)
-		prev->zone_list_next = publ->zone_list_next;
-	else if (publ->zone_list_next != publ) {
-		prev->zone_list_next = publ->zone_list_next;
-		info->zone_list = publ->zone_list_next;
-	} else {
-		info->zone_list = NULL;
-	}
+	list_del(&publ->zone_list);
 	info->zone_list_size--;
 
 	/* Remove publication from cluster scope list, if present */
 
 	if (in_own_cluster(node)) {
-		prev = info->cluster_list;
-		curr = info->cluster_list->cluster_list_next;
-		while (curr != publ) {
-			prev = curr;
-			curr = curr->cluster_list_next;
-			if (prev == info->cluster_list) {
-
-				/* Prevent endless loop for malformed list */
-
-				err("Unable to de-list cluster publication\n"
-				    "{%u%u}, node=0x%x, ref=%u, key=%u)\n",
-				    publ->type, publ->lower, publ->node,
-				    publ->ref, publ->key);
-				goto end_cluster;
-			}
-		}
-		if (publ != info->cluster_list)
-			prev->cluster_list_next = publ->cluster_list_next;
-		else if (publ->cluster_list_next != publ) {
-			prev->cluster_list_next = publ->cluster_list_next;
-			info->cluster_list = publ->cluster_list_next;
-		} else {
-			info->cluster_list = NULL;
-		}
+		list_del(&publ->cluster_list);
 		info->cluster_list_size--;
 	}
-end_cluster:
 
 	/* Remove publication from node scope list, if present */
 
 	if (node == tipc_own_addr) {
-		prev = info->node_list;
-		curr = info->node_list->node_list_next;
-		while (curr != publ) {
-			prev = curr;
-			curr = curr->node_list_next;
-			if (prev == info->node_list) {
-
-				/* Prevent endless loop for malformed list */
-
-				err("Unable to de-list node publication\n"
-				    "{%u%u}, node=0x%x, ref=%u, key=%u)\n",
-				    publ->type, publ->lower, publ->node,
-				    publ->ref, publ->key);
-				goto end_node;
-			}
-		}
-		if (publ != info->node_list)
-			prev->node_list_next = publ->node_list_next;
-		else if (publ->node_list_next != publ) {
-			prev->node_list_next = publ->node_list_next;
-			info->node_list = publ->node_list_next;
-		} else {
-			info->node_list = NULL;
-		}
+		list_del(&publ->node_list);
 		info->node_list_size--;
 	}
-end_node:
 
 	/* Contract subseq list if no more publications for that subseq */
 
-	if (!info->zone_list) {
+	if (list_empty(&info->zone_list)) {
 		kfree(info);
 		free = &nseq->sseqs[nseq->first_free--];
 		memmove(sseq, sseq + 1, (free - (sseq + 1)) * sizeof(*sseq));
@@ -530,12 +458,12 @@ static void tipc_nameseq_subscribe(struct name_seq *nseq, struct subscription *s
 		return;
 
 	while (sseq != &nseq->sseqs[nseq->first_free]) {
-		struct publication *zl = sseq->info->zone_list;
-		if (zl && tipc_subscr_overlap(s, sseq->lower, sseq->upper)) {
-			struct publication *crs = zl;
+		if (tipc_subscr_overlap(s, sseq->lower, sseq->upper)) {
+			struct publication *crs;
+			struct name_info *info = sseq->info;
 			int must_report = 1;
 
-			do {
+			list_for_each_entry(crs, &info->zone_list, zone_list) {
 				tipc_subscr_report_overlap(s,
 							   sseq->lower,
 							   sseq->upper,
@@ -544,8 +472,7 @@ static void tipc_nameseq_subscribe(struct name_seq *nseq, struct subscription *s
 							   crs->node,
 							   must_report);
 				must_report = 0;
-				crs = crs->zone_list_next;
-			} while (crs != zl);
+			}
 		}
 		sseq++;
 	}
@@ -616,9 +543,9 @@ u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *destnode)
 {
 	struct sub_seq *sseq;
 	struct name_info *info;
-	struct publication *publ = NULL;
+	struct publication *publ;
 	struct name_seq *seq;
-	u32 ref;
+	u32 ref = 0;
 
 	if (!tipc_in_scope(*destnode, tipc_own_addr))
 		return 0;
@@ -635,52 +562,56 @@ u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *destnode)
 
 	/* Closest-First Algorithm: */
 	if (likely(!*destnode)) {
-		publ = info->node_list;
-		if (publ) {
-			info->node_list = publ->node_list_next;
-found:
-			ref = publ->ref;
-			*destnode = publ->node;
-			spin_unlock_bh(&seq->lock);
-			read_unlock_bh(&tipc_nametbl_lock);
-			return ref;
-		}
-		publ = info->cluster_list;
-		if (publ) {
-			info->cluster_list = publ->cluster_list_next;
-			goto found;
-		}
-		publ = info->zone_list;
-		if (publ) {
-			info->zone_list = publ->zone_list_next;
-			goto found;
-		}
+		if (!list_empty(&info->node_list)) {
+			publ = list_first_entry(&info->node_list,
+						struct publication,
+						node_list);
+			list_move_tail(&publ->node_list,
+				       &info->node_list);
+		} else if (!list_empty(&info->cluster_list)) {
+			publ = list_first_entry(&info->cluster_list,
+						struct publication,
+						cluster_list);
+			list_move_tail(&publ->cluster_list,
+				       &info->cluster_list);
+		} else if (!list_empty(&info->zone_list)) {
+			publ = list_first_entry(&info->zone_list,
+						struct publication,
+						zone_list);
+			list_move_tail(&publ->zone_list,
+				       &info->zone_list);
+		} else
+			goto no_match;
 	}
 
 	/* Round-Robin Algorithm: */
 	else if (*destnode == tipc_own_addr) {
-		publ = info->node_list;
-		if (publ) {
-			info->node_list = publ->node_list_next;
-			goto found;
-		}
+		if (list_empty(&info->node_list))
+			goto no_match;
+		publ = list_first_entry(&info->node_list, struct publication,
+					node_list);
+		list_move_tail(&publ->node_list, &info->node_list);
 	} else if (in_own_cluster(*destnode)) {
-		publ = info->cluster_list;
-		if (publ) {
-			info->cluster_list = publ->cluster_list_next;
-			goto found;
-		}
+		if (list_empty(&info->cluster_list))
+			goto no_match;
+		publ = list_first_entry(&info->cluster_list, struct publication,
+					cluster_list);
+		list_move_tail(&publ->cluster_list, &info->cluster_list);
 	} else {
-		publ = info->zone_list;
-		if (publ) {
-			info->zone_list = publ->zone_list_next;
-			goto found;
-		}
+		if (list_empty(&info->zone_list))
+			goto no_match;
+		publ = list_first_entry(&info->zone_list, struct publication,
+					zone_list);
+		list_move_tail(&publ->zone_list, &info->zone_list);
 	}
+
+	ref = publ->ref;
+	*destnode = publ->node;
+no_match:
 	spin_unlock_bh(&seq->lock);
 not_found:
 	read_unlock_bh(&tipc_nametbl_lock);
-	return 0;
+	return ref;
 }
 
 /**
@@ -721,13 +652,9 @@ int tipc_nametbl_mc_translate(u32 type, u32 lower, u32 upper, u32 limit,
 			break;
 
 		info = sseq->info;
-		publ = info->node_list;
-		if (publ) {
-			do {
-				if (publ->scope <= limit)
-					tipc_port_list_add(dports, publ->ref);
-				publ = publ->node_list_next;
-			} while (publ != info->node_list);
+		list_for_each_entry(publ, &info->node_list, node_list) {
+			if (publ->scope <= limit)
+				tipc_port_list_add(dports, publ->ref);
 		}
 
 		if (info->cluster_list_size != info->node_list_size)
@@ -868,16 +795,19 @@ static void subseq_list(struct sub_seq *sseq, struct print_buf *buf, u32 depth,
 {
 	char portIdStr[27];
 	const char *scope_str[] = {"", " zone", " cluster", " node"};
-	struct publication *publ = sseq->info->zone_list;
+	struct publication *publ;
+	struct name_info *info;
 
 	tipc_printf(buf, "%-10u %-10u ", sseq->lower, sseq->upper);
 
-	if (depth == 2 || !publ) {
+	if (depth == 2) {
 		tipc_printf(buf, "\n");
 		return;
 	}
 
-	do {
+	info = sseq->info;
+
+	list_for_each_entry(publ, &info->zone_list, zone_list) {
 		sprintf(portIdStr, "<%u.%u.%u:%u>",
 			 tipc_zone(publ->node), tipc_cluster(publ->node),
 			 tipc_node(publ->node), publ->ref);
@@ -886,13 +816,9 @@ static void subseq_list(struct sub_seq *sseq, struct print_buf *buf, u32 depth,
 			tipc_printf(buf, "%-10u %s", publ->key,
 				    scope_str[publ->scope]);
 		}
-
-		publ = publ->zone_list_next;
-		if (publ == sseq->info->zone_list)
-			break;
-
-		tipc_printf(buf, "\n%33s", " ");
-	} while (1);
+		if (!list_is_last(&publ->zone_list, &info->zone_list))
+			tipc_printf(buf, "\n%33s", " ");
+	};
 
 	tipc_printf(buf, "\n");
 }
diff --git a/net/tipc/name_table.h b/net/tipc/name_table.h
index d228bd68265..62d77e5e902 100644
--- a/net/tipc/name_table.h
+++ b/net/tipc/name_table.h
@@ -2,7 +2,7 @@
  * net/tipc/name_table.h: Include file for TIPC name table code
  *
  * Copyright (c) 2000-2006, Ericsson AB
- * Copyright (c) 2004-2005, Wind River Systems
+ * Copyright (c) 2004-2005, 2010-2011, Wind River Systems
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -61,9 +61,9 @@ struct port_list;
  * @subscr: subscription to "node down" event (for off-node publications only)
  * @local_list: adjacent entries in list of publications made by this node
  * @pport_list: adjacent entries in list of publications made by this port
- * @node_list: next matching name seq publication with >= node scope
- * @cluster_list: next matching name seq publication with >= cluster scope
- * @zone_list: next matching name seq publication with >= zone scope
+ * @node_list: adjacent matching name seq publications with >= node scope
+ * @cluster_list: adjacent matching name seq publications with >= cluster scope
+ * @zone_list: adjacent matching name seq publications with >= zone scope
  *
  * Note that the node list, cluster list, and zone list are circular lists.
  */
@@ -79,9 +79,9 @@ struct publication {
 	struct tipc_node_subscr subscr;
 	struct list_head local_list;
 	struct list_head pport_list;
-	struct publication *node_list_next;
-	struct publication *cluster_list_next;
-	struct publication *zone_list_next;
+	struct list_head node_list;
+	struct list_head cluster_list;
+	struct list_head zone_list;
 };
 
 
-- 
cgit v1.2.3-70-g09d2


From 8af4638a297b43c4929fdc01456b7f0698de0c0e Mon Sep 17 00:00:00 2001
From: Allan Stephens <allan.stephens@windriver.com>
Date: Mon, 30 May 2011 11:27:50 -0400
Subject: tipc: Eliminate checks for empty zone list during name translation

Gets rid of a pair of checks to see if a name sequence entry in
TIPC's name table has an empty zone list. These checks are pointless
since the zone list can never be empty (i.e. as soon as the list
becomes empty the associated name sequence entry is deleted).

Signed-off-by: Allan Stephens <allan.stephens@windriver.com>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
---
 net/tipc/name_table.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

(limited to 'net/tipc/name_table.c')

diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 7d85cc1ace0..46e6b6c2ecc 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -574,14 +574,13 @@ u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *destnode)
 						cluster_list);
 			list_move_tail(&publ->cluster_list,
 				       &info->cluster_list);
-		} else if (!list_empty(&info->zone_list)) {
+		} else {
 			publ = list_first_entry(&info->zone_list,
 						struct publication,
 						zone_list);
 			list_move_tail(&publ->zone_list,
 				       &info->zone_list);
-		} else
-			goto no_match;
+		}
 	}
 
 	/* Round-Robin Algorithm: */
@@ -598,8 +597,6 @@ u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *destnode)
 					cluster_list);
 		list_move_tail(&publ->cluster_list, &info->cluster_list);
 	} else {
-		if (list_empty(&info->zone_list))
-			goto no_match;
 		publ = list_first_entry(&info->zone_list, struct publication,
 					zone_list);
 		list_move_tail(&publ->zone_list, &info->zone_list);
-- 
cgit v1.2.3-70-g09d2