Netdev List
 help / color / mirror / Atom feed
From: Jon Maloy <jon.maloy@ericsson.com>
To: davem@davemloft.net
Cc: netdev@vger.kernel.org,
	Paul Gortmaker <paul.gortmaker@windriver.com>,
	erik.hugne@ericsson.com, ying.xue@windriver.com,
	maloy@donjonn.com, tipc-discussion@lists.sourceforge.net,
	Jon Maloy <jon.maloy@ericsson.com>
Subject: [PATCH net-next v2 12/14] tipc: delay delete of link when failover is needed
Date: Thu, 13 Feb 2014 17:29:16 -0500	[thread overview]
Message-ID: <1392330558-19048-13-git-send-email-jon.maloy@ericsson.com> (raw)
In-Reply-To: <1392330558-19048-1-git-send-email-jon.maloy@ericsson.com>

When a bearer is disabled, all its attached links are deleted.
Ideally, we should do link failover to redundant links on other bearers,
if there are any, in such cases. This would be consistent with current
behavior when a link is reset, but not deleted. However, due to the
complexity involved, and the (wrongly) perceived low demand for this
feature, it was never implemented until now.

We mark the doomed link for deletion with a new flag, but wait until the
failover process is finished before we actually delete it. With the
improved link tunnelling/failover code introduced earlier in this commit
series, it is now easy to identify a spot in the code where the failover
is finished and it is safe to delete the marked link. Moreover, the test
for the flag and the deletion can be done synchronously, and outside the
most time critical data path.

Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Reviewed-by: Ying Xue <ying.xue@windriver.com>
---
 net/tipc/bearer.c |   12 ++++++------
 net/tipc/link.c   |   31 ++++++++++++++++++++++---------
 net/tipc/link.h   |    2 +-
 net/tipc/node.c   |    8 +++++++-
 4 files changed, 36 insertions(+), 17 deletions(-)

diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 4931eea..60caa45 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -51,7 +51,7 @@ static struct tipc_media * const media_info_array[] = {
 
 struct tipc_bearer tipc_bearers[MAX_BEARERS];
 
-static void bearer_disable(struct tipc_bearer *b_ptr);
+static void bearer_disable(struct tipc_bearer *b_ptr, bool shutting_down);
 
 /**
  * tipc_media_find - locates specified media object by name
@@ -331,7 +331,7 @@ restart:
 
 	res = tipc_disc_create(b_ptr, &b_ptr->bcast_addr, disc_domain);
 	if (res) {
-		bearer_disable(b_ptr);
+		bearer_disable(b_ptr, false);
 		pr_warn("Bearer <%s> rejected, discovery object creation failed\n",
 			name);
 		goto exit;
@@ -363,14 +363,14 @@ static int tipc_reset_bearer(struct tipc_bearer *b_ptr)
  *
  * Note: This routine assumes caller holds tipc_net_lock.
  */
-static void bearer_disable(struct tipc_bearer *b_ptr)
+static void bearer_disable(struct tipc_bearer *b_ptr, bool shutting_down)
 {
 	struct tipc_link_req *temp_req;
 
 	pr_info("Disabling bearer <%s>\n", b_ptr->name);
 	spin_lock_bh(&b_ptr->lock);
 	b_ptr->media->disable_media(b_ptr);
-	tipc_link_delete_list(b_ptr->identity);
+	tipc_link_delete_list(b_ptr->identity, shutting_down);
 	temp_req = b_ptr->link_req;
 	b_ptr->link_req = NULL;
 	spin_unlock_bh(&b_ptr->lock);
@@ -392,7 +392,7 @@ int tipc_disable_bearer(const char *name)
 		pr_warn("Attempt to disable unknown bearer <%s>\n", name);
 		res = -EINVAL;
 	} else {
-		bearer_disable(b_ptr);
+		bearer_disable(b_ptr, false);
 		res = 0;
 	}
 	write_unlock_bh(&tipc_net_lock);
@@ -612,6 +612,6 @@ void tipc_bearer_stop(void)
 
 	for (i = 0; i < MAX_BEARERS; i++) {
 		if (tipc_bearers[i].active)
-			bearer_disable(&tipc_bearers[i]);
+			bearer_disable(&tipc_bearers[i], true);
 	}
 }
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 663623c..0307516 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -281,7 +281,7 @@ struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
 }
 
 
-void tipc_link_delete_list(unsigned int bearer_id)
+void tipc_link_delete_list(unsigned int bearer_id, bool shutting_down)
 {
 	struct tipc_link *l_ptr;
 	struct tipc_node *n_ptr;
@@ -291,12 +291,20 @@ void tipc_link_delete_list(unsigned int bearer_id)
 		l_ptr = n_ptr->links[bearer_id];
 		if (l_ptr) {
 			tipc_link_reset(l_ptr);
-			tipc_node_detach_link(n_ptr, l_ptr);
-			spin_unlock_bh(&n_ptr->lock);
-
-			/* Nobody else can access this link now: */
-			del_timer_sync(&l_ptr->timer);
-			kfree(l_ptr);
+			if (shutting_down || !tipc_node_is_up(n_ptr)) {
+				tipc_node_detach_link(l_ptr->owner, l_ptr);
+				tipc_link_reset_fragments(l_ptr);
+				spin_unlock_bh(&n_ptr->lock);
+
+				/* Nobody else can access this link now: */
+				del_timer_sync(&l_ptr->timer);
+				kfree(l_ptr);
+			} else {
+				/* Detach/delete when failover is finished: */
+				l_ptr->flags |= LINK_STOPPED;
+				spin_unlock_bh(&n_ptr->lock);
+				del_timer_sync(&l_ptr->timer);
+			}
 			continue;
 		}
 		spin_unlock_bh(&n_ptr->lock);
@@ -481,6 +489,9 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
 	struct tipc_link *other;
 	u32 cont_intv = l_ptr->continuity_interval;
 
+	if (l_ptr->flags & LINK_STOPPED)
+		return;
+
 	if (!(l_ptr->flags & LINK_STARTED) && (event != STARTING_EVT))
 		return;		/* Not yet. */
 
@@ -2167,8 +2178,11 @@ static struct sk_buff *tipc_link_failover_rcv(struct tipc_link *l_ptr,
 					   &buf);
 		}
 	}
-
 exit:
+	if ((l_ptr->exp_msg_count == 0) && (l_ptr->flags & LINK_STOPPED)) {
+		tipc_node_detach_link(l_ptr->owner, l_ptr);
+		kfree(l_ptr);
+	}
 	return buf;
 }
 
@@ -2201,7 +2215,6 @@ static int tipc_link_tunnel_rcv(struct tipc_node *n_ptr,
 		*buf = tipc_link_failover_rcv(l_ptr, t_buf);
 	else
 		pr_warn("%sunknown tunnel pkt received\n", link_co_err);
-
 exit:
 	kfree_skb(t_buf);
 	return *buf != NULL;
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 3340fc1..45b9cd0 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -214,7 +214,7 @@ struct tipc_port;
 struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
 			      struct tipc_bearer *b_ptr,
 			      const struct tipc_media_addr *media_addr);
-void tipc_link_delete_list(unsigned int bearer_id);
+void tipc_link_delete_list(unsigned int bearer_id, bool shutting_down);
 void tipc_link_failover_send_queue(struct tipc_link *l_ptr);
 void tipc_link_dup_send_queue(struct tipc_link *l_ptr,
 			      struct tipc_link *dest);
diff --git a/net/tipc/node.c b/net/tipc/node.c
index efe4d41..833324b 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -249,7 +249,13 @@ void tipc_node_attach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
 
 void tipc_node_detach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
 {
-	n_ptr->links[l_ptr->b_ptr->identity] = NULL;
+	int i;
+
+	for (i = 0; i < MAX_BEARERS; i++) {
+		if (l_ptr == n_ptr->links[i])
+			break;
+	}
+	n_ptr->links[i] = NULL;
 	atomic_dec(&tipc_num_links);
 	n_ptr->link_cnt--;
 }
-- 
1.7.9.5

  parent reply	other threads:[~2014-02-13 22:29 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-02-13 22:29 [PATCH net-next v2 00/14] tipc: clean up media and bearer layer Jon Maloy
2014-02-13 22:29 ` [PATCH net-next v2 01/14] tipc: stricter behavior of message reassembly function Jon Maloy
2014-02-13 22:29 ` [PATCH net-next v2 02/14] tipc: move code for resetting links from bearer.c to link.c Jon Maloy
2014-02-13 22:29 ` [PATCH net-next v2 03/14] tipc: move code for deleting " Jon Maloy
2014-02-13 22:29 ` [PATCH net-next v2 04/14] tipc: redefine 'started' flag in struct link to bitmap Jon Maloy
2014-02-13 22:29 ` [PATCH net-next v2 05/14] tipc: remove 'links' list from tipc_bearer struct Jon Maloy
2014-02-13 22:29 ` [PATCH net-next v2 06/14] tipc: change reception of tunnelled duplicate packets Jon Maloy
2014-02-13 22:29 ` [PATCH net-next v2 07/14] tipc: change reception of tunnelled failover packets Jon Maloy
2014-02-13 22:29 ` [PATCH net-next v2 08/14] tipc: change signature of tunnelling reception function Jon Maloy
2014-02-13 22:29 ` [PATCH net-next v2 09/14] tipc: more cleanup " Jon Maloy
2014-02-13 22:29 ` [PATCH net-next v2 10/14] tipc: rename stack variables in function tipc_link_tunnel_rcv Jon Maloy
2014-02-13 22:29 ` [PATCH net-next v2 11/14] tipc: changes to general packet reception algorithm Jon Maloy
2014-02-13 22:29 ` Jon Maloy [this message]
2014-02-13 22:29 ` [PATCH net-next v2 13/14] tipc: remove bearer_lock from tipc_bearer struct Jon Maloy
2014-02-13 22:29 ` [PATCH net-next v2 14/14] tipc: add node_lock protection to link lookup function Jon Maloy
2014-02-13 22:57 ` [PATCH net-next v2 00/14] tipc: clean up media and bearer layer David Miller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1392330558-19048-13-git-send-email-jon.maloy@ericsson.com \
    --to=jon.maloy@ericsson.com \
    --cc=davem@davemloft.net \
    --cc=erik.hugne@ericsson.com \
    --cc=maloy@donjonn.com \
    --cc=netdev@vger.kernel.org \
    --cc=paul.gortmaker@windriver.com \
    --cc=tipc-discussion@lists.sourceforge.net \
    --cc=ying.xue@windriver.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox