All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 00/17] tipc: Merge port and socket layer code
@ 2014-08-22 22:09 Jon Maloy
  2014-08-22 22:09 ` [PATCH net-next 01/17] tipc: fix message importance range check Jon Maloy
                   ` (17 more replies)
  0 siblings, 18 replies; 22+ messages in thread
From: Jon Maloy @ 2014-08-22 22:09 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, Paul Gortmaker, tipc-discussion

After the removal of the TIPC native interface, there is no reason to
keep a distinction between a "generic" port layer and a "specific"
socket layer in the code. Throughout the last months, we have posted
several series that aimed at facilitating removal of the port layer,
and in particular the port_lock spinlock, which in reality duplicates
the role normally kept by lock_sock()/bh_lock_sock().

In this series, we finalize this work, by making a significant number of
changes to the link, node, port and socket code, all with the aim of
reducing dependencies between the layers. In the final commits, we then
remove the port spinlock, port.c and port.h altogether.

After this series, we have a socket layer that has only few dependencies
to the rest of the stack, so that it should be possible to continue
cleanups of its code without significantly affecting other code.

It should be noted that commit ##1 and 2 are already in 'net' 
(ac32c7f705692b92fe12dcbe88fe87136fdfff6f and 
02784f1b05b8f241c8180af88869e717e2758593), but not yet in net-next.
Since they are prerequisites for the rest of the series to apply, I
prepend them to the series.

David S. Miller (1):
  tipc: Fix build.

Erik Hugne (1):
  tipc: fix message importance range check

Jon Maloy (15):
  tipc: introduce new function tipc_msg_create()
  tipc: use pseudo message to wake up sockets after link congestion
  tipc: use message to abort connections when losing contact to node
  tipc: clean up socket timer function
  tipc: eliminate function tipc_port_shutdown()
  tipc: eliminate port_connect()/port_disconnect() functions
  tipc: redefine message acknowledge function
  tipc: eliminate functions tipc_port_init and tipc_port_destroy
  tipc: use registry when scanning sockets
  tipc: replace port pointer with socket pointer in registry
  tipc: remove port_lock
  tipc: remove source file port.c
  tipc: remove include file port.h
  tipc: remove files ref.h and ref.c
  tipc: merge struct tipc_port into struct tipc_sock

 net/tipc/Makefile     |    2 +-
 net/tipc/bcast.c      |    8 +-
 net/tipc/config.c     |    4 +-
 net/tipc/core.c       |    9 +-
 net/tipc/core.h       |    5 +-
 net/tipc/link.c       |  120 +++----
 net/tipc/link.h       |    7 +-
 net/tipc/msg.c        |   38 ++-
 net/tipc/msg.h        |    5 +
 net/tipc/name_table.c |    1 -
 net/tipc/net.c        |    3 +-
 net/tipc/node.c       |   90 +++++
 net/tipc/node.h       |    7 +-
 net/tipc/port.c       |  514 ----------------------------
 net/tipc/port.h       |  187 -----------
 net/tipc/ref.c        |  266 ---------------
 net/tipc/ref.h        |   48 ---
 net/tipc/socket.c     |  884 +++++++++++++++++++++++++++++++++++++++++--------
 net/tipc/socket.h     |   55 +--
 net/tipc/subscr.c     |    1 -
 20 files changed, 956 insertions(+), 1298 deletions(-)
 delete mode 100644 net/tipc/port.c
 delete mode 100644 net/tipc/port.h
 delete mode 100644 net/tipc/ref.c
 delete mode 100644 net/tipc/ref.h

-- 
1.7.9.5


------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH net-next 01/17] tipc: fix message importance range check
  2014-08-22 22:09 [PATCH net-next 00/17] tipc: Merge port and socket layer code Jon Maloy
@ 2014-08-22 22:09 ` Jon Maloy
  2014-08-22 22:09 ` [PATCH net-next 02/17] tipc: Fix build Jon Maloy
                   ` (16 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Jon Maloy @ 2014-08-22 22:09 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, Paul Gortmaker, tipc-discussion

From: Erik Hugne <erik.hugne@ericsson.com>

Commit 3b4f302d8578 ("tipc: eliminate
redundant locking") introduced a bug by removing the sanity check
for message importance, allowing programs to assign any value to
the msg_user field. This will mess up the packet reception logic
and may cause random link resets.

Signed-off-by: Erik Hugne <erik.hugne@ericsson.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
 net/tipc/port.h   |    4 +++-
 net/tipc/socket.c |    2 +-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/net/tipc/port.h b/net/tipc/port.h
index 3f93454..a69118f 100644
--- a/net/tipc/port.h
+++ b/net/tipc/port.h
@@ -179,8 +179,10 @@ static inline int tipc_port_importance(struct tipc_port *port)
 	return msg_importance(&port->phdr);
 }
 
-static inline void tipc_port_set_importance(struct tipc_port *port, int imp)
+static inline int tipc_port_set_importance(struct tipc_port *port, int imp)
 {
+	if (imp > TIPC_CRITICAL_IMPORTANCE)
+		return -EINVAL
 	msg_set_importance(&port->phdr, (u32)imp);
 }
 
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 7d423ee..ff8c811 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -1973,7 +1973,7 @@ static int tipc_setsockopt(struct socket *sock, int lvl, int opt,
 
 	switch (opt) {
 	case TIPC_IMPORTANCE:
-		tipc_port_set_importance(port, value);
+		res = tipc_port_set_importance(port, value);
 		break;
 	case TIPC_SRC_DROPPABLE:
 		if (sock->type != SOCK_STREAM)
-- 
1.7.9.5


------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH net-next 02/17] tipc: Fix build.
  2014-08-22 22:09 [PATCH net-next 00/17] tipc: Merge port and socket layer code Jon Maloy
  2014-08-22 22:09 ` [PATCH net-next 01/17] tipc: fix message importance range check Jon Maloy
@ 2014-08-22 22:09 ` Jon Maloy
  2014-08-25 10:21   ` Neil Horman
  2014-08-22 22:09 ` [PATCH net-next 03/17] tipc: introduce new function tipc_msg_create() Jon Maloy
                   ` (15 subsequent siblings)
  17 siblings, 1 reply; 22+ messages in thread
From: Jon Maloy @ 2014-08-22 22:09 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, Paul Gortmaker, tipc-discussion

From: "David S. Miller" <davem@davemloft.net>

Missing semicolon in range check fix.

Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
 net/tipc/port.h |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/tipc/port.h b/net/tipc/port.h
index a69118f..3087da3 100644
--- a/net/tipc/port.h
+++ b/net/tipc/port.h
@@ -182,8 +182,9 @@ static inline int tipc_port_importance(struct tipc_port *port)
 static inline int tipc_port_set_importance(struct tipc_port *port, int imp)
 {
 	if (imp > TIPC_CRITICAL_IMPORTANCE)
-		return -EINVAL
+		return -EINVAL;
 	msg_set_importance(&port->phdr, (u32)imp);
+	return 0;
 }
 
 #endif
-- 
1.7.9.5


------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH net-next 03/17] tipc: introduce new function tipc_msg_create()
  2014-08-22 22:09 [PATCH net-next 00/17] tipc: Merge port and socket layer code Jon Maloy
  2014-08-22 22:09 ` [PATCH net-next 01/17] tipc: fix message importance range check Jon Maloy
  2014-08-22 22:09 ` [PATCH net-next 02/17] tipc: Fix build Jon Maloy
@ 2014-08-22 22:09 ` Jon Maloy
  2014-08-22 22:09 ` [PATCH net-next 04/17] tipc: use pseudo message to wake up sockets after link congestion Jon Maloy
                   ` (14 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Jon Maloy @ 2014-08-22 22:09 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, Paul Gortmaker, tipc-discussion

The function tipc_msg_init() has turned out to be of limited value
in many cases. It take too few parameters to be usable for creating
a complete message, it makes too many assumptions about what the
message should be used for, and it does not allocate any buffer to
be returned to the caller.

Therefore, we now introduce the new function tipc_msg_create(), which
takes all the parameters needed to create a full message, and returns
a buffer of the requested size. The new function will be very useful
for the changes we will be doing in later commits in this series.

Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Ying Xue <ying.xue@windriver.com>
---
 net/tipc/msg.c |   31 +++++++++++++++++++++++++++++--
 net/tipc/msg.h |    4 ++++
 2 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index 9680be6..fdb92e2 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -56,8 +56,35 @@ void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, u32 hsize,
 	msg_set_size(m, hsize);
 	msg_set_prevnode(m, tipc_own_addr);
 	msg_set_type(m, type);
-	msg_set_orignode(m, tipc_own_addr);
-	msg_set_destnode(m, destnode);
+	if (hsize > SHORT_H_SIZE) {
+		msg_set_orignode(m, tipc_own_addr);
+		msg_set_destnode(m, destnode);
+	}
+}
+
+struct sk_buff *tipc_msg_create(uint user, uint type, uint hdr_sz,
+				uint data_sz, u32 dnode, u32 onode,
+				u32 dport, u32 oport, int errcode)
+{
+	struct tipc_msg *msg;
+	struct sk_buff *buf;
+
+	buf = tipc_buf_acquire(hdr_sz + data_sz);
+	if (unlikely(!buf))
+		return NULL;
+
+	msg = buf_msg(buf);
+	tipc_msg_init(msg, user, type, hdr_sz, dnode);
+	msg_set_size(msg, hdr_sz + data_sz);
+	msg_set_prevnode(msg, onode);
+	msg_set_origport(msg, oport);
+	msg_set_destport(msg, dport);
+	msg_set_errcode(msg, errcode);
+	if (hdr_sz > SHORT_H_SIZE) {
+		msg_set_orignode(msg, onode);
+		msg_set_destnode(msg, dnode);
+	}
+	return buf;
 }
 
 /* tipc_buf_append(): Append a buffer to the fragment list of another buffer
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index 462fa19..3045b2c 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -732,6 +732,10 @@ int tipc_msg_eval(struct sk_buff *buf, u32 *dnode);
 void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, u32 hsize,
 		   u32 destnode);
 
+struct sk_buff *tipc_msg_create(uint user, uint type, uint hdr_sz,
+				uint data_sz, u32 dnode, u32 onode,
+				u32 dport, u32 oport, int errcode);
+
 int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf);
 
 bool tipc_msg_bundle(struct sk_buff *bbuf, struct sk_buff *buf, u32 mtu);
-- 
1.7.9.5


------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH net-next 04/17] tipc: use pseudo message to wake up sockets after link congestion
  2014-08-22 22:09 [PATCH net-next 00/17] tipc: Merge port and socket layer code Jon Maloy
                   ` (2 preceding siblings ...)
  2014-08-22 22:09 ` [PATCH net-next 03/17] tipc: introduce new function tipc_msg_create() Jon Maloy
@ 2014-08-22 22:09 ` Jon Maloy
  2014-08-22 22:09 ` [PATCH net-next 05/17] tipc: use message to abort connections when losing contact to node Jon Maloy
                   ` (13 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Jon Maloy @ 2014-08-22 22:09 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, Paul Gortmaker, tipc-discussion

The current link implementation keeps a linked list of blocked ports/
sockets that is populated when there is link congestion. The purpose
of this is to let the link know which users to wake up when the
congestion abates.

This adds unnecessary complexity to the data structure and the code,
since it forces us to involve the link each time we want to delete
a socket. It also forces us to grab the spinlock port_lock within
the scope of node_lock. We want to get rid of this direct dependence,
as well as the deadlock hazard resulting from the usage of port_lock.

In this commit, we instead let the link keep list of a "wakeup" pseudo
messages for use in such situations. Those messages are sent to the
pending sockets via the ordinary message reception path, and wake up
the socket's owner when they are received.

This enables us to get rid of the 'waiting_ports' linked lists in struct
tipc_port that manifest this direct reference. As a consequence, we can
eliminate another BH entry into the socket, and hence the need to grab
port_lock. This is a further step in our effort to remove port_lock
altogether.

Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Ying Xue <ying.xue@windriver.com>
---
 net/tipc/bcast.c  |    7 ++--
 net/tipc/core.h   |    5 ++-
 net/tipc/link.c   |  119 ++++++++++++++++++++++++-----------------------------
 net/tipc/link.h   |    7 ++--
 net/tipc/msg.c    |    7 +++-
 net/tipc/msg.h    |    1 +
 net/tipc/node.c   |   12 ++++++
 net/tipc/node.h   |    4 +-
 net/tipc/port.c   |    2 -
 net/tipc/port.h   |    4 --
 net/tipc/socket.c |   15 +++++--
 net/tipc/socket.h |    7 +---
 12 files changed, 99 insertions(+), 91 deletions(-)

diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index dd13bfa..9510fb2 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -300,8 +300,8 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked)
 		tipc_link_push_queue(bcl);
 		bclink_set_last_sent();
 	}
-	if (unlikely(released && !list_empty(&bcl->waiting_ports)))
-		tipc_link_wakeup_ports(bcl, 0);
+	if (unlikely(released && !skb_queue_empty(&bcl->waiting_sks)))
+		bclink->node.action_flags |= TIPC_WAKEUP_USERS;
 exit:
 	tipc_bclink_unlock();
 }
@@ -840,9 +840,10 @@ int tipc_bclink_init(void)
 	sprintf(bcbearer->media.name, "tipc-broadcast");
 
 	spin_lock_init(&bclink->lock);
-	INIT_LIST_HEAD(&bcl->waiting_ports);
+	__skb_queue_head_init(&bcl->waiting_sks);
 	bcl->next_out_no = 1;
 	spin_lock_init(&bclink->node.lock);
+	__skb_queue_head_init(&bclink->node.waiting_sks);
 	bcl->owner = &bclink->node;
 	bcl->max_pkt = MAX_PKT_DEFAULT_MCAST;
 	tipc_link_set_queue_limits(bcl, BCLINK_WIN_DEFAULT);
diff --git a/net/tipc/core.h b/net/tipc/core.h
index bb26ed1..d2607a8 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -187,8 +187,11 @@ static inline void k_term_timer(struct timer_list *timer)
 
 struct tipc_skb_cb {
 	void *handle;
-	bool deferred;
 	struct sk_buff *tail;
+	bool deferred;
+	bool wakeup_pending;
+	u16 chain_sz;
+	u16 chain_imp;
 };
 
 #define TIPC_SKB_CB(__skb) ((struct tipc_skb_cb *)&((__skb)->cb[0]))
diff --git a/net/tipc/link.c b/net/tipc/link.c
index fb1485d..6c775a1 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -275,7 +275,7 @@ struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
 	link_init_max_pkt(l_ptr);
 
 	l_ptr->next_out_no = 1;
-	INIT_LIST_HEAD(&l_ptr->waiting_ports);
+	__skb_queue_head_init(&l_ptr->waiting_sks);
 
 	link_reset_statistics(l_ptr);
 
@@ -322,66 +322,47 @@ void tipc_link_delete_list(unsigned int bearer_id, bool shutting_down)
 }
 
 /**
- * link_schedule_port - schedule port for deferred sending
- * @l_ptr: pointer to link
- * @origport: reference to sending port
- * @sz: amount of data to be sent
- *
- * Schedules port for renewed sending of messages after link congestion
- * has abated.
+ * link_schedule_user - schedule user for wakeup after congestion
+ * @link: congested link
+ * @oport: sending port
+ * @chain_sz: size of buffer chain that was attempted sent
+ * @imp: importance of message attempted sent
+ * Create pseudo msg to send back to user when congestion abates
  */
-static int link_schedule_port(struct tipc_link *l_ptr, u32 origport, u32 sz)
+static bool link_schedule_user(struct tipc_link *link, u32 oport,
+			       uint chain_sz, uint imp)
 {
-	struct tipc_port *p_ptr;
-	struct tipc_sock *tsk;
+	struct sk_buff *buf;
 
-	spin_lock_bh(&tipc_port_list_lock);
-	p_ptr = tipc_port_lock(origport);
-	if (p_ptr) {
-		if (!list_empty(&p_ptr->wait_list))
-			goto exit;
-		tsk = tipc_port_to_sock(p_ptr);
-		tsk->link_cong = 1;
-		p_ptr->waiting_pkts = 1 + ((sz - 1) / l_ptr->max_pkt);
-		list_add_tail(&p_ptr->wait_list, &l_ptr->waiting_ports);
-		l_ptr->stats.link_congs++;
-exit:
-		tipc_port_unlock(p_ptr);
-	}
-	spin_unlock_bh(&tipc_port_list_lock);
-	return -ELINKCONG;
+	buf = tipc_msg_create(SOCK_WAKEUP, 0, INT_H_SIZE, 0, tipc_own_addr,
+			      tipc_own_addr, oport, 0, 0);
+	if (!buf)
+		return false;
+	TIPC_SKB_CB(buf)->chain_sz = chain_sz;
+	TIPC_SKB_CB(buf)->chain_imp = imp;
+	__skb_queue_tail(&link->waiting_sks, buf);
+	link->stats.link_congs++;
+	return true;
 }
 
-void tipc_link_wakeup_ports(struct tipc_link *l_ptr, int all)
+/**
+ * link_prepare_wakeup - prepare users for wakeup after congestion
+ * @link: congested link
+ * Move a number of waiting users, as permitted by available space in
+ * the send queue, from link wait queue to node wait queue for wakeup
+ */
+static void link_prepare_wakeup(struct tipc_link *link)
 {
-	struct tipc_port *p_ptr;
-	struct tipc_sock *tsk;
-	struct tipc_port *temp_p_ptr;
-	int win = l_ptr->queue_limit[0] - l_ptr->out_queue_size;
-
-	if (all)
-		win = 100000;
-	if (win <= 0)
-		return;
-	if (!spin_trylock_bh(&tipc_port_list_lock))
-		return;
-	if (link_congested(l_ptr))
-		goto exit;
-	list_for_each_entry_safe(p_ptr, temp_p_ptr, &l_ptr->waiting_ports,
-				 wait_list) {
-		if (win <= 0)
+	struct sk_buff_head *wq = &link->waiting_sks;
+	struct sk_buff *buf;
+	uint pend_qsz = link->out_queue_size;
+
+	for (buf = skb_peek(wq); buf; buf = skb_peek(wq)) {
+		if (pend_qsz >= link->queue_limit[TIPC_SKB_CB(buf)->chain_imp])
 			break;
-		tsk = tipc_port_to_sock(p_ptr);
-		list_del_init(&p_ptr->wait_list);
-		spin_lock_bh(p_ptr->lock);
-		tsk->link_cong = 0;
-		tipc_sock_wakeup(tsk);
-		win -= p_ptr->waiting_pkts;
-		spin_unlock_bh(p_ptr->lock);
+		pend_qsz += TIPC_SKB_CB(buf)->chain_sz;
+		__skb_queue_tail(&link->owner->waiting_sks, __skb_dequeue(wq));
 	}
-
-exit:
-	spin_unlock_bh(&tipc_port_list_lock);
 }
 
 /**
@@ -423,6 +404,7 @@ void tipc_link_reset(struct tipc_link *l_ptr)
 	u32 prev_state = l_ptr->state;
 	u32 checkpoint = l_ptr->next_in_no;
 	int was_active_link = tipc_link_is_active(l_ptr);
+	struct tipc_node *owner = l_ptr->owner;
 
 	msg_set_session(l_ptr->pmsg, ((msg_session(l_ptr->pmsg) + 1) & 0xffff));
 
@@ -450,9 +432,10 @@ void tipc_link_reset(struct tipc_link *l_ptr)
 	kfree_skb(l_ptr->proto_msg_queue);
 	l_ptr->proto_msg_queue = NULL;
 	kfree_skb_list(l_ptr->oldest_deferred_in);
-	if (!list_empty(&l_ptr->waiting_ports))
-		tipc_link_wakeup_ports(l_ptr, 1);
-
+	if (!skb_queue_empty(&l_ptr->waiting_sks)) {
+		skb_queue_splice_init(&l_ptr->waiting_sks, &owner->waiting_sks);
+		owner->action_flags |= TIPC_WAKEUP_USERS;
+	}
 	l_ptr->retransm_queue_head = 0;
 	l_ptr->retransm_queue_size = 0;
 	l_ptr->last_out = NULL;
@@ -688,19 +671,23 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
 static int tipc_link_cong(struct tipc_link *link, struct sk_buff *buf)
 {
 	struct tipc_msg *msg = buf_msg(buf);
-	uint psz = msg_size(msg);
 	uint imp = tipc_msg_tot_importance(msg);
 	u32 oport = msg_tot_origport(msg);
 
-	if (likely(imp <= TIPC_CRITICAL_IMPORTANCE)) {
-		if (!msg_errcode(msg) && !msg_reroute_cnt(msg)) {
-			link_schedule_port(link, oport, psz);
-			return -ELINKCONG;
-		}
-	} else {
+	if (unlikely(imp > TIPC_CRITICAL_IMPORTANCE)) {
 		pr_warn("%s<%s>, send queue full", link_rst_msg, link->name);
 		tipc_link_reset(link);
+		goto drop;
 	}
+	if (unlikely(msg_errcode(msg)))
+		goto drop;
+	if (unlikely(msg_reroute_cnt(msg)))
+		goto drop;
+	if (TIPC_SKB_CB(buf)->wakeup_pending)
+		return -ELINKCONG;
+	if (link_schedule_user(link, oport, TIPC_SKB_CB(buf)->chain_sz, imp))
+		return -ELINKCONG;
+drop:
 	kfree_skb_list(buf);
 	return -EHOSTUNREACH;
 }
@@ -1202,8 +1189,10 @@ void tipc_rcv(struct sk_buff *head, struct tipc_bearer *b_ptr)
 		if (unlikely(l_ptr->next_out))
 			tipc_link_push_queue(l_ptr);
 
-		if (unlikely(!list_empty(&l_ptr->waiting_ports)))
-			tipc_link_wakeup_ports(l_ptr, 0);
+		if (released && !skb_queue_empty(&l_ptr->waiting_sks)) {
+			link_prepare_wakeup(l_ptr);
+			l_ptr->owner->action_flags |= TIPC_WAKEUP_USERS;
+		}
 
 		/* Process the incoming packet */
 		if (unlikely(!link_working_working(l_ptr))) {
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 782983c..b567a34 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -1,7 +1,7 @@
 /*
  * net/tipc/link.h: Include file for TIPC link code
  *
- * Copyright (c) 1995-2006, 2013, Ericsson AB
+ * Copyright (c) 1995-2006, 2013-2014, Ericsson AB
  * Copyright (c) 2004-2005, 2010-2011, Wind River Systems
  * All rights reserved.
  *
@@ -133,7 +133,7 @@ struct tipc_stats {
  * @retransm_queue_size: number of messages to retransmit
  * @retransm_queue_head: sequence number of first message to retransmit
  * @next_out: ptr to first unsent outbound message in queue
- * @waiting_ports: linked list of ports waiting for link congestion to abate
+ * @waiting_sks: linked list of sockets waiting for link congestion to abate
  * @long_msg_seq_no: next identifier to use for outbound fragmented messages
  * @reasm_buf: head of partially reassembled inbound message fragments
  * @stats: collects statistics regarding link activity
@@ -194,7 +194,7 @@ struct tipc_link {
 	u32 retransm_queue_size;
 	u32 retransm_queue_head;
 	struct sk_buff *next_out;
-	struct list_head waiting_ports;
+	struct sk_buff_head waiting_sks;
 
 	/* Fragmentation/reassembly */
 	u32 long_msg_seq_no;
@@ -235,7 +235,6 @@ void tipc_link_proto_xmit(struct tipc_link *l_ptr, u32 msg_typ, int prob,
 void tipc_link_push_queue(struct tipc_link *l_ptr);
 u32 tipc_link_defer_pkt(struct sk_buff **head, struct sk_buff **tail,
 			struct sk_buff *buf);
-void tipc_link_wakeup_ports(struct tipc_link *l_ptr, int all);
 void tipc_link_set_queue_limits(struct tipc_link *l_ptr, u32 window);
 void tipc_link_retransmit(struct tipc_link *l_ptr,
 			  struct sk_buff *start, u32 retransmits);
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index fdb92e2..74745a4 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -182,7 +182,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct iovec const *iov,
 	struct sk_buff *buf, *prev;
 	char *pktpos;
 	int rc;
-
+	uint chain_sz = 0;
 	msg_set_size(mhdr, msz);
 
 	/* No fragmentation needed? */
@@ -193,6 +193,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct iovec const *iov,
 			return -ENOMEM;
 		skb_copy_to_linear_data(buf, mhdr, mhsz);
 		pktpos = buf->data + mhsz;
+		TIPC_SKB_CB(buf)->chain_sz = 1;
 		if (!dsz || !memcpy_fromiovecend(pktpos, iov, offset, dsz))
 			return dsz;
 		rc = -EFAULT;
@@ -209,6 +210,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct iovec const *iov,
 	*chain = buf = tipc_buf_acquire(pktmax);
 	if (!buf)
 		return -ENOMEM;
+	chain_sz = 1;
 	pktpos = buf->data;
 	skb_copy_to_linear_data(buf, &pkthdr, INT_H_SIZE);
 	pktpos += INT_H_SIZE;
@@ -242,6 +244,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct iovec const *iov,
 			rc = -ENOMEM;
 			goto error;
 		}
+		chain_sz++;
 		prev->next = buf;
 		msg_set_type(&pkthdr, FRAGMENT);
 		msg_set_size(&pkthdr, pktsz);
@@ -251,7 +254,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct iovec const *iov,
 		pktrem = pktsz - INT_H_SIZE;
 
 	} while (1);
-
+	TIPC_SKB_CB(*chain)->chain_sz = chain_sz;
 	msg_set_type(buf_msg(buf), LAST_FRAGMENT);
 	return dsz;
 error:
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index 3045b2c..0ea7b69 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -442,6 +442,7 @@ static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m)
 #define  NAME_DISTRIBUTOR     11
 #define  MSG_FRAGMENTER       12
 #define  LINK_CONFIG          13
+#define  SOCK_WAKEUP          14       /* pseudo user */
 
 /*
  *  Connection management protocol message types
diff --git a/net/tipc/node.c b/net/tipc/node.c
index f706929..6ea2c15 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -38,6 +38,7 @@
 #include "config.h"
 #include "node.h"
 #include "name_distr.h"
+#include "socket.h"
 
 #define NODE_HTABLE_SIZE 512
 
@@ -100,6 +101,7 @@ struct tipc_node *tipc_node_create(u32 addr)
 	INIT_HLIST_NODE(&n_ptr->hash);
 	INIT_LIST_HEAD(&n_ptr->list);
 	INIT_LIST_HEAD(&n_ptr->nsub);
+	__skb_queue_head_init(&n_ptr->waiting_sks);
 
 	hlist_add_head_rcu(&n_ptr->hash, &node_htable[tipc_hashfn(addr)]);
 
@@ -474,6 +476,7 @@ int tipc_node_get_linkname(u32 bearer_id, u32 addr, char *linkname, size_t len)
 void tipc_node_unlock(struct tipc_node *node)
 {
 	LIST_HEAD(nsub_list);
+	struct sk_buff_head waiting_sks;
 	u32 addr = 0;
 
 	if (likely(!node->action_flags)) {
@@ -481,6 +484,11 @@ void tipc_node_unlock(struct tipc_node *node)
 		return;
 	}
 
+	__skb_queue_head_init(&waiting_sks);
+	if (node->action_flags & TIPC_WAKEUP_USERS) {
+		skb_queue_splice_init(&node->waiting_sks, &waiting_sks);
+		node->action_flags &= ~TIPC_WAKEUP_USERS;
+	}
 	if (node->action_flags & TIPC_NOTIFY_NODE_DOWN) {
 		list_replace_init(&node->nsub, &nsub_list);
 		node->action_flags &= ~TIPC_NOTIFY_NODE_DOWN;
@@ -491,8 +499,12 @@ void tipc_node_unlock(struct tipc_node *node)
 	}
 	spin_unlock_bh(&node->lock);
 
+	while (!skb_queue_empty(&waiting_sks))
+		tipc_sk_rcv(__skb_dequeue(&waiting_sks));
+
 	if (!list_empty(&nsub_list))
 		tipc_nodesub_notify(&nsub_list);
+
 	if (addr)
 		tipc_named_node_up(addr);
 }
diff --git a/net/tipc/node.h b/net/tipc/node.h
index b61716a..2ebf9e8b 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -58,7 +58,8 @@ enum {
 	TIPC_WAIT_PEER_LINKS_DOWN	= (1 << 1),
 	TIPC_WAIT_OWN_LINKS_DOWN	= (1 << 2),
 	TIPC_NOTIFY_NODE_DOWN		= (1 << 3),
-	TIPC_NOTIFY_NODE_UP		= (1 << 4)
+	TIPC_NOTIFY_NODE_UP		= (1 << 4),
+	TIPC_WAKEUP_USERS		= (1 << 5)
 };
 
 /**
@@ -115,6 +116,7 @@ struct tipc_node {
 	int working_links;
 	u32 signature;
 	struct list_head nsub;
+	struct sk_buff_head waiting_sks;
 	struct rcu_head rcu;
 };
 
diff --git a/net/tipc/port.c b/net/tipc/port.c
index 7e096a5..b58a777 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -92,7 +92,6 @@ u32 tipc_port_init(struct tipc_port *p_ptr,
 
 	p_ptr->max_pkt = MAX_PKT_DEFAULT;
 	p_ptr->ref = ref;
-	INIT_LIST_HEAD(&p_ptr->wait_list);
 	INIT_LIST_HEAD(&p_ptr->subscription.nodesub_list);
 	k_init_timer(&p_ptr->timer, (Handler)port_timeout, ref);
 	INIT_LIST_HEAD(&p_ptr->publications);
@@ -134,7 +133,6 @@ void tipc_port_destroy(struct tipc_port *p_ptr)
 	}
 	spin_lock_bh(&tipc_port_list_lock);
 	list_del(&p_ptr->port_list);
-	list_del(&p_ptr->wait_list);
 	spin_unlock_bh(&tipc_port_list_lock);
 	k_term_timer(&p_ptr->timer);
 }
diff --git a/net/tipc/port.h b/net/tipc/port.h
index 3087da3..6cdc7de 100644
--- a/net/tipc/port.h
+++ b/net/tipc/port.h
@@ -58,8 +58,6 @@
  * @ref: unique reference to port in TIPC object registry
  * @phdr: preformatted message header used when sending messages
  * @port_list: adjacent ports in TIPC's global list of ports
- * @wait_list: adjacent ports in list of ports waiting on link congestion
- * @waiting_pkts:
  * @publications: list of publications for port
  * @pub_count: total # of publications port has made during its lifetime
  * @probing_state:
@@ -77,8 +75,6 @@ struct tipc_port {
 	u32 ref;
 	struct tipc_msg phdr;
 	struct list_head port_list;
-	struct list_head wait_list;
-	u32 waiting_pkts;
 	struct list_head publications;
 	u32 pub_count;
 	u32 probing_state;
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index ff8c811..a8be4d2 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -579,6 +579,7 @@ new_mtu:
 			goto new_mtu;
 		if (rc != -ELINKCONG)
 			break;
+		tipc_sk(sk)->link_cong = 1;
 		rc = tipc_wait_for_sndmsg(sock, &timeo);
 		if (rc)
 			kfree_skb_list(buf);
@@ -651,7 +652,7 @@ static int tipc_sk_proto_rcv(struct tipc_sock *tsk, u32 *dnode,
 		conn_cong = tipc_sk_conn_cong(tsk);
 		tsk->sent_unacked -= msg_msgcnt(msg);
 		if (conn_cong)
-			tipc_sock_wakeup(tsk);
+			tsk->sk.sk_write_space(&tsk->sk);
 	} else if (msg_type(msg) == CONN_PROBE) {
 		if (!tipc_msg_reverse(buf, dnode, TIPC_OK))
 			return TIPC_OK;
@@ -826,6 +827,7 @@ new_mtu:
 		goto exit;
 
 	do {
+		TIPC_SKB_CB(buf)->wakeup_pending = tsk->link_cong;
 		rc = tipc_link_xmit(buf, dnode, tsk->port.ref);
 		if (likely(rc >= 0)) {
 			if (sock->state != SS_READY)
@@ -835,10 +837,9 @@ new_mtu:
 		}
 		if (rc == -EMSGSIZE)
 			goto new_mtu;
-
 		if (rc != -ELINKCONG)
 			break;
-
+		tsk->link_cong = 1;
 		rc = tipc_wait_for_sndmsg(sock, &timeo);
 		if (rc)
 			kfree_skb_list(buf);
@@ -953,6 +954,7 @@ next:
 			}
 			if (rc != -ELINKCONG)
 				break;
+			tsk->link_cong = 1;
 		}
 		rc = tipc_wait_for_sndpkt(sock, &timeo);
 		if (rc)
@@ -1518,6 +1520,13 @@ static int filter_rcv(struct sock *sk, struct sk_buff *buf)
 	if (unlikely(msg_user(msg) == CONN_MANAGER))
 		return tipc_sk_proto_rcv(tsk, &onode, buf);
 
+	if (unlikely(msg_user(msg) == SOCK_WAKEUP)) {
+		kfree_skb(buf);
+		tsk->link_cong = 0;
+		sk->sk_write_space(sk);
+		return TIPC_OK;
+	}
+
 	/* Reject message if it is wrong sort of message for socket */
 	if (msg_type(msg) > TIPC_DIRECT_MSG)
 		return -TIPC_ERR_NO_PORT;
diff --git a/net/tipc/socket.h b/net/tipc/socket.h
index 43b75b3..1405633 100644
--- a/net/tipc/socket.h
+++ b/net/tipc/socket.h
@@ -58,7 +58,7 @@ struct tipc_sock {
 	struct tipc_port port;
 	unsigned int conn_timeout;
 	atomic_t dupl_rcvcnt;
-	int link_cong;
+	bool link_cong;
 	uint sent_unacked;
 	uint rcv_unacked;
 };
@@ -73,11 +73,6 @@ static inline struct tipc_sock *tipc_port_to_sock(const struct tipc_port *port)
 	return container_of(port, struct tipc_sock, port);
 }
 
-static inline void tipc_sock_wakeup(struct tipc_sock *tsk)
-{
-	tsk->sk.sk_write_space(&tsk->sk);
-}
-
 static inline int tipc_sk_conn_cong(struct tipc_sock *tsk)
 {
 	return tsk->sent_unacked >= TIPC_FLOWCTRL_WIN;
-- 
1.7.9.5


------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH net-next 05/17] tipc: use message to abort connections when losing contact to node
  2014-08-22 22:09 [PATCH net-next 00/17] tipc: Merge port and socket layer code Jon Maloy
                   ` (3 preceding siblings ...)
  2014-08-22 22:09 ` [PATCH net-next 04/17] tipc: use pseudo message to wake up sockets after link congestion Jon Maloy
@ 2014-08-22 22:09 ` Jon Maloy
  2014-08-22 22:09 ` [PATCH net-next 06/17] tipc: clean up socket timer function Jon Maloy
                   ` (12 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Jon Maloy @ 2014-08-22 22:09 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, Paul Gortmaker, tipc-discussion

In the current implementation, each 'struct tipc_node' instance keeps
a linked list of those ports/sockets that are connected to the node
represented by that struct. The purpose of this is to let the node
object know which sockets to alert when it loses contact with its peer
node, i.e., which sockets need to have their connections aborted.

This entails an unwanted direct reference from the node structure
back to the port/socket structure, and a need to grab port_lock
when we have to make an upcall to the port. We want to get rid of
this unecessary BH entry point into the socket, and also eliminate
its use of port_lock.

In this commit, we instead let the node struct keep list of "connected
socket" structs, which each represents a connected socket, but is
allocated independently by the node at the moment of connection. If
the node loses contact with its peer node, the list is traversed, and
a "connection abort" message is created for each entry in the list. The
message is sent to it respective connected socket using the ordinary
data path, and the receiving socket aborts its connections upon reception
of the message.

This enables us to get rid of the direct reference from 'struct node' to
´struct port', and another unwanted BH access point to the latter.

Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Ying Xue <ying.xue@windriver.com>
---
 net/tipc/node.c |   78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 net/tipc/node.h |    3 +++
 net/tipc/port.c |   29 +++------------------
 3 files changed, 85 insertions(+), 25 deletions(-)

diff --git a/net/tipc/node.c b/net/tipc/node.c
index 6ea2c15..17e6378 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -51,6 +51,13 @@ static u32 tipc_num_nodes;
 static u32 tipc_num_links;
 static DEFINE_SPINLOCK(node_list_lock);
 
+struct tipc_sock_conn {
+	u32 port;
+	u32 peer_port;
+	u32 peer_node;
+	struct list_head list;
+};
+
 /*
  * A trivial power-of-two bitmask technique is used for speed, since this
  * operation is done for every incoming TIPC packet. The number of hash table
@@ -101,6 +108,7 @@ struct tipc_node *tipc_node_create(u32 addr)
 	INIT_HLIST_NODE(&n_ptr->hash);
 	INIT_LIST_HEAD(&n_ptr->list);
 	INIT_LIST_HEAD(&n_ptr->nsub);
+	INIT_LIST_HEAD(&n_ptr->conn_sks);
 	__skb_queue_head_init(&n_ptr->waiting_sks);
 
 	hlist_add_head_rcu(&n_ptr->hash, &node_htable[tipc_hashfn(addr)]);
@@ -138,6 +146,71 @@ void tipc_node_stop(void)
 	spin_unlock_bh(&node_list_lock);
 }
 
+int tipc_node_add_conn(u32 dnode, u32 port, u32 peer_port)
+{
+	struct tipc_node *node;
+	struct tipc_sock_conn *conn;
+
+	if (in_own_node(dnode))
+		return 0;
+
+	node = tipc_node_find(dnode);
+	if (!node) {
+		pr_warn("Connecting sock to node 0x%x failed\n", dnode);
+		return -EHOSTUNREACH;
+	}
+	conn = kmalloc(sizeof(*conn), GFP_ATOMIC);
+	if (!conn)
+		return -EHOSTUNREACH;
+	conn->peer_node = dnode;
+	conn->port = port;
+	conn->peer_port = peer_port;
+
+	tipc_node_lock(node);
+	list_add_tail(&conn->list, &node->conn_sks);
+	tipc_node_unlock(node);
+	return 0;
+}
+
+void tipc_node_remove_conn(u32 dnode, u32 port)
+{
+	struct tipc_node *node;
+	struct tipc_sock_conn *conn, *safe;
+
+	if (in_own_node(dnode))
+		return;
+
+	node = tipc_node_find(dnode);
+	if (!node)
+		return;
+
+	tipc_node_lock(node);
+	list_for_each_entry_safe(conn, safe, &node->conn_sks, list) {
+		if (port != conn->port)
+			continue;
+		list_del(&conn->list);
+		kfree(conn);
+	}
+	tipc_node_unlock(node);
+}
+
+void tipc_node_abort_sock_conns(struct list_head *conns)
+{
+	struct tipc_sock_conn *conn, *safe;
+	struct sk_buff *buf;
+
+	list_for_each_entry_safe(conn, safe, conns, list) {
+		buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG,
+				      SHORT_H_SIZE, 0, tipc_own_addr,
+				      conn->peer_node, conn->port,
+				      conn->peer_port, TIPC_ERR_NO_NODE);
+		if (likely(buf))
+			tipc_sk_rcv(buf);
+		list_del(&conn->list);
+		kfree(conn);
+	}
+}
+
 /**
  * tipc_node_link_up - handle addition of link
  *
@@ -476,6 +549,7 @@ int tipc_node_get_linkname(u32 bearer_id, u32 addr, char *linkname, size_t len)
 void tipc_node_unlock(struct tipc_node *node)
 {
 	LIST_HEAD(nsub_list);
+	LIST_HEAD(conn_sks);
 	struct sk_buff_head waiting_sks;
 	u32 addr = 0;
 
@@ -491,6 +565,7 @@ void tipc_node_unlock(struct tipc_node *node)
 	}
 	if (node->action_flags & TIPC_NOTIFY_NODE_DOWN) {
 		list_replace_init(&node->nsub, &nsub_list);
+		list_replace_init(&node->conn_sks, &conn_sks);
 		node->action_flags &= ~TIPC_NOTIFY_NODE_DOWN;
 	}
 	if (node->action_flags & TIPC_NOTIFY_NODE_UP) {
@@ -502,6 +577,9 @@ void tipc_node_unlock(struct tipc_node *node)
 	while (!skb_queue_empty(&waiting_sks))
 		tipc_sk_rcv(__skb_dequeue(&waiting_sks));
 
+	if (!list_empty(&conn_sks))
+		tipc_node_abort_sock_conns(&conn_sks);
+
 	if (!list_empty(&nsub_list))
 		tipc_nodesub_notify(&nsub_list);
 
diff --git a/net/tipc/node.h b/net/tipc/node.h
index 2ebf9e8b..522d6f3 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -117,6 +117,7 @@ struct tipc_node {
 	u32 signature;
 	struct list_head nsub;
 	struct sk_buff_head waiting_sks;
+	struct list_head conn_sks;
 	struct rcu_head rcu;
 };
 
@@ -135,6 +136,8 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
 struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space);
 int tipc_node_get_linkname(u32 bearer_id, u32 node, char *linkname, size_t len);
 void tipc_node_unlock(struct tipc_node *node);
+int tipc_node_add_conn(u32 dnode, u32 port, u32 peer_port);
+void tipc_node_remove_conn(u32 dnode, u32 port);
 
 static inline void tipc_node_lock(struct tipc_node *node)
 {
diff --git a/net/tipc/port.c b/net/tipc/port.c
index b58a777..edbd83d 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -48,7 +48,6 @@
 DEFINE_SPINLOCK(tipc_port_list_lock);
 
 static LIST_HEAD(ports);
-static void port_handle_node_down(unsigned long ref);
 static struct sk_buff *port_build_self_abort_msg(struct tipc_port *, u32 err);
 static struct sk_buff *port_build_peer_abort_msg(struct tipc_port *, u32 err);
 static void port_timeout(unsigned long ref);
@@ -126,10 +125,10 @@ void tipc_port_destroy(struct tipc_port *p_ptr)
 	k_cancel_timer(&p_ptr->timer);
 	if (p_ptr->connected) {
 		buf = port_build_peer_abort_msg(p_ptr, TIPC_ERR_NO_PORT);
-		tipc_nodesub_unsubscribe(&p_ptr->subscription);
 		msg = buf_msg(buf);
 		peer = msg_destnode(msg);
 		tipc_link_xmit(buf, peer, msg_link_selector(msg));
+		tipc_node_remove_conn(peer, p_ptr->ref);
 	}
 	spin_lock_bh(&tipc_port_list_lock);
 	list_del(&p_ptr->port_list);
@@ -188,22 +187,6 @@ static void port_timeout(unsigned long ref)
 	tipc_link_xmit(buf, msg_destnode(msg),	msg_link_selector(msg));
 }
 
-
-static void port_handle_node_down(unsigned long ref)
-{
-	struct tipc_port *p_ptr = tipc_port_lock(ref);
-	struct sk_buff *buf = NULL;
-	struct tipc_msg *msg = NULL;
-
-	if (!p_ptr)
-		return;
-	buf = port_build_self_abort_msg(p_ptr, TIPC_ERR_NO_NODE);
-	tipc_port_unlock(p_ptr);
-	msg = buf_msg(buf);
-	tipc_link_xmit(buf, msg_destnode(msg),	msg_link_selector(msg));
-}
-
-
 static struct sk_buff *port_build_self_abort_msg(struct tipc_port *p_ptr, u32 err)
 {
 	struct sk_buff *buf = port_build_peer_abort_msg(p_ptr, err);
@@ -217,7 +200,6 @@ static struct sk_buff *port_build_self_abort_msg(struct tipc_port *p_ptr, u32 er
 	return buf;
 }
 
-
 static struct sk_buff *port_build_peer_abort_msg(struct tipc_port *p_ptr, u32 err)
 {
 	struct sk_buff *buf;
@@ -447,11 +429,8 @@ int __tipc_port_connect(u32 ref, struct tipc_port *p_ptr,
 	p_ptr->probing_state = TIPC_CONN_OK;
 	p_ptr->connected = 1;
 	k_start_timer(&p_ptr->timer, p_ptr->probing_interval);
-
-	tipc_nodesub_subscribe(&p_ptr->subscription, peer->node,
-			  (void *)(unsigned long)ref,
-			  (net_ev_handler)port_handle_node_down);
-	res = 0;
+	res = tipc_node_add_conn(tipc_port_peernode(p_ptr), p_ptr->ref,
+				 tipc_port_peerport(p_ptr));
 exit:
 	p_ptr->max_pkt = tipc_node_get_mtu(peer->node, ref);
 	return res;
@@ -467,7 +446,7 @@ int __tipc_port_disconnect(struct tipc_port *tp_ptr)
 	if (tp_ptr->connected) {
 		tp_ptr->connected = 0;
 		/* let timer expire on it's own to avoid deadlock! */
-		tipc_nodesub_unsubscribe(&tp_ptr->subscription);
+		tipc_node_remove_conn(tipc_port_peernode(tp_ptr), tp_ptr->ref);
 		return 0;
 	}
 
-- 
1.7.9.5


------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/
_______________________________________________
tipc-discussion mailing list
tipc-discussion@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tipc-discussion

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH net-next 06/17] tipc: clean up socket timer function
  2014-08-22 22:09 [PATCH net-next 00/17] tipc: Merge port and socket layer code Jon Maloy
                   ` (4 preceding siblings ...)
  2014-08-22 22:09 ` [PATCH net-next 05/17] tipc: use message to abort connections when losing contact to node Jon Maloy
@ 2014-08-22 22:09 ` Jon Maloy
  2014-08-22 22:09 ` [PATCH net-next 07/17] tipc: eliminate function tipc_port_shutdown() Jon Maloy
                   ` (11 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Jon Maloy @ 2014-08-22 22:09 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, Paul Gortmaker, tipc-discussion

The last remaining BH upcall to the socket, apart for the message
reception function tipc_sk_rcv(), is the timer function.

We prefer to let this function continue executing in BH, since it only
does read-acces to semi-permanent data, but we make three changes to it:

1) We introduce a bh_lock_sock()/bh_unlock_sock() inside the scope
   of port_lock.  This is a preparation for replacing port_lock with
   bh_lock_sock() at the locations where it is still used.

2) We move the function from port.c to socket.c, as a further step
   of eliminating the port code level altogether.

3) We let it make use of the newly introduced tipc_msg_create()
   function. This enables us to get rid of three context specific
   functions (port_create_self_abort_msg() etc.) in port.c

Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Ying Xue <ying.xue@windriver.com>
---
 net/tipc/port.c   |  126 ++++++++++-------------------------------------------
 net/tipc/socket.c |   46 +++++++++++++++++++
 2 files changed, 69 insertions(+), 103 deletions(-)

diff --git a/net/tipc/port.c b/net/tipc/port.c
index edbd83d..6de79f2 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -48,9 +48,6 @@
 DEFINE_SPINLOCK(tipc_port_list_lock);
 
 static LIST_HEAD(ports);
-static struct sk_buff *port_build_self_abort_msg(struct tipc_port *, u32 err);
-static struct sk_buff *port_build_peer_abort_msg(struct tipc_port *, u32 err);
-static void port_timeout(unsigned long ref);
 
 /**
  * tipc_port_peer_msg - verify message was sent by connected port's peer
@@ -92,7 +89,6 @@ u32 tipc_port_init(struct tipc_port *p_ptr,
 	p_ptr->max_pkt = MAX_PKT_DEFAULT;
 	p_ptr->ref = ref;
 	INIT_LIST_HEAD(&p_ptr->subscription.nodesub_list);
-	k_init_timer(&p_ptr->timer, (Handler)port_timeout, ref);
 	INIT_LIST_HEAD(&p_ptr->publications);
 	INIT_LIST_HEAD(&p_ptr->port_list);
 
@@ -114,7 +110,7 @@ void tipc_port_destroy(struct tipc_port *p_ptr)
 {
 	struct sk_buff *buf = NULL;
 	struct tipc_msg *msg = NULL;
-	u32 peer;
+	u32 peer_node;
 
 	tipc_withdraw(p_ptr, 0, NULL);
 
@@ -124,11 +120,16 @@ void tipc_port_destroy(struct tipc_port *p_ptr)
 
 	k_cancel_timer(&p_ptr->timer);
 	if (p_ptr->connected) {
-		buf = port_build_peer_abort_msg(p_ptr, TIPC_ERR_NO_PORT);
-		msg = buf_msg(buf);
-		peer = msg_destnode(msg);
-		tipc_link_xmit(buf, peer, msg_link_selector(msg));
-		tipc_node_remove_conn(peer, p_ptr->ref);
+		peer_node = tipc_port_peernode(p_ptr);
+		buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG,
+				      SHORT_H_SIZE, 0, peer_node,
+				      tipc_own_addr, tipc_port_peerport(p_ptr),
+				      p_ptr->ref, TIPC_ERR_NO_PORT);
+		if (buf) {
+			msg = buf_msg(buf);
+			tipc_link_xmit(buf, peer_node, msg_link_selector(msg));
+		}
+		tipc_node_remove_conn(peer_node, p_ptr->ref);
 	}
 	spin_lock_bh(&tipc_port_list_lock);
 	list_del(&p_ptr->port_list);
@@ -136,94 +137,6 @@ void tipc_port_destroy(struct tipc_port *p_ptr)
 	k_term_timer(&p_ptr->timer);
 }
 
-/*
- * port_build_proto_msg(): create connection protocol message for port
- *
- * On entry the port must be locked and connected.
- */
-static struct sk_buff *port_build_proto_msg(struct tipc_port *p_ptr,
-					    u32 type, u32 ack)
-{
-	struct sk_buff *buf;
-	struct tipc_msg *msg;
-
-	buf = tipc_buf_acquire(INT_H_SIZE);
-	if (buf) {
-		msg = buf_msg(buf);
-		tipc_msg_init(msg, CONN_MANAGER, type, INT_H_SIZE,
-			      tipc_port_peernode(p_ptr));
-		msg_set_destport(msg, tipc_port_peerport(p_ptr));
-		msg_set_origport(msg, p_ptr->ref);
-		msg_set_msgcnt(msg, ack);
-		buf->next = NULL;
-	}
-	return buf;
-}
-
-static void port_timeout(unsigned long ref)
-{
-	struct tipc_port *p_ptr = tipc_port_lock(ref);
-	struct sk_buff *buf = NULL;
-	struct tipc_msg *msg = NULL;
-
-	if (!p_ptr)
-		return;
-
-	if (!p_ptr->connected) {
-		tipc_port_unlock(p_ptr);
-		return;
-	}
-
-	/* Last probe answered ? */
-	if (p_ptr->probing_state == TIPC_CONN_PROBING) {
-		buf = port_build_self_abort_msg(p_ptr, TIPC_ERR_NO_PORT);
-	} else {
-		buf = port_build_proto_msg(p_ptr, CONN_PROBE, 0);
-		p_ptr->probing_state = TIPC_CONN_PROBING;
-		k_start_timer(&p_ptr->timer, p_ptr->probing_interval);
-	}
-	tipc_port_unlock(p_ptr);
-	msg = buf_msg(buf);
-	tipc_link_xmit(buf, msg_destnode(msg),	msg_link_selector(msg));
-}
-
-static struct sk_buff *port_build_self_abort_msg(struct tipc_port *p_ptr, u32 err)
-{
-	struct sk_buff *buf = port_build_peer_abort_msg(p_ptr, err);
-
-	if (buf) {
-		struct tipc_msg *msg = buf_msg(buf);
-		msg_swap_words(msg, 4, 5);
-		msg_swap_words(msg, 6, 7);
-		buf->next = NULL;
-	}
-	return buf;
-}
-
-static struct sk_buff *port_build_peer_abort_msg(struct tipc_port *p_ptr, u32 err)
-{
-	struct sk_buff *buf;
-	struct tipc_msg *msg;
-	u32 imp;
-
-	if (!p_ptr->connected)
-		return NULL;
-
-	buf = tipc_buf_acquire(BASIC_H_SIZE);
-	if (buf) {
-		msg = buf_msg(buf);
-		memcpy(msg, &p_ptr->phdr, BASIC_H_SIZE);
-		msg_set_hdr_sz(msg, BASIC_H_SIZE);
-		msg_set_size(msg, BASIC_H_SIZE);
-		imp = msg_importance(msg);
-		if (imp < TIPC_CRITICAL_IMPORTANCE)
-			msg_set_importance(msg, ++imp);
-		msg_set_errcode(msg, err);
-		buf->next = NULL;
-	}
-	return buf;
-}
-
 static int port_print(struct tipc_port *p_ptr, char *buf, int len, int full_id)
 {
 	struct publication *publ;
@@ -321,12 +234,15 @@ void tipc_acknowledge(u32 ref, u32 ack)
 	if (!p_ptr)
 		return;
 	if (p_ptr->connected)
-		buf = port_build_proto_msg(p_ptr, CONN_ACK, ack);
-
+		buf = tipc_msg_create(CONN_MANAGER, CONN_ACK, INT_H_SIZE,
+				      0, tipc_port_peernode(p_ptr),
+				      tipc_own_addr, tipc_port_peerport(p_ptr),
+				      p_ptr->ref, TIPC_OK);
 	tipc_port_unlock(p_ptr);
 	if (!buf)
 		return;
 	msg = buf_msg(buf);
+	msg_set_msgcnt(msg, ack);
 	tipc_link_xmit(buf, msg_destnode(msg),	msg_link_selector(msg));
 }
 
@@ -478,14 +394,18 @@ int tipc_port_shutdown(u32 ref)
 	struct tipc_msg *msg;
 	struct tipc_port *p_ptr;
 	struct sk_buff *buf = NULL;
+	u32 peer_node;
 
 	p_ptr = tipc_port_lock(ref);
 	if (!p_ptr)
 		return -EINVAL;
-
-	buf = port_build_peer_abort_msg(p_ptr, TIPC_CONN_SHUTDOWN);
+	peer_node = tipc_port_peernode(p_ptr);
+	buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG,
+			      SHORT_H_SIZE, 0, peer_node,
+			      tipc_own_addr, tipc_port_peerport(p_ptr),
+			      p_ptr->ref, TIPC_CONN_SHUTDOWN);
 	tipc_port_unlock(p_ptr);
 	msg = buf_msg(buf);
-	tipc_link_xmit(buf, msg_destnode(msg),	msg_link_selector(msg));
+	tipc_link_xmit(buf, peer_node,	msg_link_selector(msg));
 	return tipc_port_disconnect(ref);
 }
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index a8be4d2..5f8376e 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -53,6 +53,7 @@ static void tipc_write_space(struct sock *sk);
 static int tipc_release(struct socket *sock);
 static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags);
 static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p);
+static void tipc_sk_timeout(unsigned long ref);
 
 static const struct proto_ops packet_ops;
 static const struct proto_ops stream_ops;
@@ -202,6 +203,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
 	sock->state = state;
 
 	sock_init_data(sock, sk);
+	k_init_timer(&port->timer, (Handler)tipc_sk_timeout, ref);
 	sk->sk_backlog_rcv = tipc_backlog_rcv;
 	sk->sk_rcvbuf = sysctl_tipc_rmem[1];
 	sk->sk_data_ready = tipc_data_ready;
@@ -1946,6 +1948,50 @@ restart:
 	return res;
 }
 
+static void tipc_sk_timeout(unsigned long ref)
+{
+	struct tipc_port *port = tipc_port_lock(ref);
+	struct tipc_sock *tsk;
+	struct sock *sk;
+	struct sk_buff *buf = NULL;
+	struct tipc_msg *msg = NULL;
+	u32 peer_port, peer_node;
+
+	if (!port)
+		return;
+
+	if (!port->connected) {
+		tipc_port_unlock(port);
+		return;
+	}
+	tsk = tipc_port_to_sock(port);
+	sk = &tsk->sk;
+	bh_lock_sock(sk);
+	peer_port = tipc_port_peerport(port);
+	peer_node = tipc_port_peernode(port);
+
+	if (port->probing_state == TIPC_CONN_PROBING) {
+		/* Previous probe not answered -> self abort */
+		buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG,
+				      SHORT_H_SIZE, 0, tipc_own_addr,
+				      peer_node, ref, peer_port,
+				      TIPC_ERR_NO_PORT);
+	} else {
+		buf = tipc_msg_create(CONN_MANAGER, CONN_PROBE, INT_H_SIZE,
+				      0, peer_node, tipc_own_addr,
+				      peer_port, ref, TIPC_OK);
+		port->probing_state = TIPC_CONN_PROBING;
+		k_start_timer(&port->timer, port->probing_interval);
+	}
+	bh_unlock_sock(sk);
+	tipc_port_unlock(port);
+	if (!buf)
+		return;
+
+	msg = buf_msg(buf);
+	tipc_link_xmit(buf, msg_destnode(msg),	msg_link_selector(msg));
+}
+
 /**
  * tipc_setsockopt - set socket option
  * @sock: socket structure
-- 
1.7.9.5


------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH net-next 07/17] tipc: eliminate function tipc_port_shutdown()
  2014-08-22 22:09 [PATCH net-next 00/17] tipc: Merge port and socket layer code Jon Maloy
                   ` (5 preceding siblings ...)
  2014-08-22 22:09 ` [PATCH net-next 06/17] tipc: clean up socket timer function Jon Maloy
@ 2014-08-22 22:09 ` Jon Maloy
  2014-08-22 22:09 ` [PATCH net-next 08/17] tipc: eliminate port_connect()/port_disconnect() functions Jon Maloy
                   ` (10 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Jon Maloy @ 2014-08-22 22:09 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, Paul Gortmaker, tipc-discussion

tipc_port_shutdown() is a remnant from the now obsolete native
interface. As such it grabs port_lock in order to protect itself
from concurrent BH processing.

However, after the recent changes to the port/socket upcalls, sockets
are now basically single-threaded, and all execution, except the read-only
tipc_sk_timer(), is executing within the protection of lock_sock(). So
the use of port_lock is not needed here.

In this commit we eliminate the whole function, and merge it into its
only caller, tipc_shutdown().

Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Ying Xue <ying.xue@windriver.com>
---
 net/tipc/port.c   |   24 ------------------------
 net/tipc/port.h   |    2 --
 net/tipc/socket.c |   15 +++++++++++----
 3 files changed, 11 insertions(+), 30 deletions(-)

diff --git a/net/tipc/port.c b/net/tipc/port.c
index 6de79f2..3ad092b 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -385,27 +385,3 @@ int tipc_port_disconnect(u32 ref)
 	tipc_port_unlock(p_ptr);
 	return res;
 }
-
-/*
- * tipc_port_shutdown(): Send a SHUTDOWN msg to peer and disconnect
- */
-int tipc_port_shutdown(u32 ref)
-{
-	struct tipc_msg *msg;
-	struct tipc_port *p_ptr;
-	struct sk_buff *buf = NULL;
-	u32 peer_node;
-
-	p_ptr = tipc_port_lock(ref);
-	if (!p_ptr)
-		return -EINVAL;
-	peer_node = tipc_port_peernode(p_ptr);
-	buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG,
-			      SHORT_H_SIZE, 0, peer_node,
-			      tipc_own_addr, tipc_port_peerport(p_ptr),
-			      p_ptr->ref, TIPC_CONN_SHUTDOWN);
-	tipc_port_unlock(p_ptr);
-	msg = buf_msg(buf);
-	tipc_link_xmit(buf, peer_node,	msg_link_selector(msg));
-	return tipc_port_disconnect(ref);
-}
diff --git a/net/tipc/port.h b/net/tipc/port.h
index 6cdc7de..f5762f9 100644
--- a/net/tipc/port.h
+++ b/net/tipc/port.h
@@ -106,8 +106,6 @@ int tipc_port_connect(u32 portref, struct tipc_portid const *port);
 
 int tipc_port_disconnect(u32 portref);
 
-int tipc_port_shutdown(u32 ref);
-
 /*
  * The following routines require that the port be locked on entry
  */
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 5f8376e..f202d47 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -1899,7 +1899,7 @@ static int tipc_shutdown(struct socket *sock, int how)
 	struct tipc_sock *tsk = tipc_sk(sk);
 	struct tipc_port *port = &tsk->port;
 	struct sk_buff *buf;
-	u32 peer;
+	u32 dnode;
 	int res;
 
 	if (how != SHUT_RDWR)
@@ -1920,10 +1920,17 @@ restart:
 				goto restart;
 			}
 			tipc_port_disconnect(port->ref);
-			if (tipc_msg_reverse(buf, &peer, TIPC_CONN_SHUTDOWN))
-				tipc_link_xmit(buf, peer, 0);
+			if (tipc_msg_reverse(buf, &dnode, TIPC_CONN_SHUTDOWN))
+				tipc_link_xmit(buf, dnode, port->ref);
 		} else {
-			tipc_port_shutdown(port->ref);
+			dnode = tipc_port_peernode(port);
+			buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE,
+					      TIPC_CONN_MSG, SHORT_H_SIZE,
+					      0, dnode, tipc_own_addr,
+					      tipc_port_peerport(port),
+					      port->ref, TIPC_CONN_SHUTDOWN);
+			tipc_link_xmit(buf, dnode, port->ref);
+			__tipc_port_disconnect(port);
 		}
 
 		sock->state = SS_DISCONNECTING;
-- 
1.7.9.5


------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH net-next 08/17] tipc: eliminate port_connect()/port_disconnect() functions
  2014-08-22 22:09 [PATCH net-next 00/17] tipc: Merge port and socket layer code Jon Maloy
                   ` (6 preceding siblings ...)
  2014-08-22 22:09 ` [PATCH net-next 07/17] tipc: eliminate function tipc_port_shutdown() Jon Maloy
@ 2014-08-22 22:09 ` Jon Maloy
  2014-08-22 22:09 ` [PATCH net-next 09/17] tipc: redefine message acknowledge function Jon Maloy
                   ` (9 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Jon Maloy @ 2014-08-22 22:09 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, Paul Gortmaker, tipc-discussion

tipc_port_connect()/tipc_port_disconnect() are remnants of the obsolete
native API. Their only task is to grab port_lock and call the functions
__tipc_port_connect()/__tipc_port_disconnect() respectively, which will
perform the actual state change.

Since socket/port exection now is single-threaded the use of port_lock
is not needed any more, so we can safely replace the two functions with
their lock-free counterparts.

In this commit, we remove the two functions. Furthermore, the contents
of __tipc_port_disconnect() is so trivial that we choose to eliminate
that function too, expanding its functionality into tipc_shutdown().
__tipc_port_connect() is simplified, moved to socket.c, and given the
more correct name tipc_sk_finish_conn(). Finally, we eliminate the
function auto_connect(), and expand its contents into filter_connect().

Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Ying Xue <ying.xue@windriver.com>
---
 net/tipc/port.c   |   84 -----------------------------------------------------
 net/tipc/port.h   |   10 -------
 net/tipc/socket.c |   75 +++++++++++++++++++++++------------------------
 3 files changed, 37 insertions(+), 132 deletions(-)

diff --git a/net/tipc/port.c b/net/tipc/port.c
index 3ad092b..2f96719 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -40,9 +40,6 @@
 #include "name_table.h"
 #include "socket.h"
 
-/* Connection management: */
-#define PROBING_INTERVAL 3600000	/* [ms] => 1 h */
-
 #define MAX_REJECT_SIZE 1024
 
 DEFINE_SPINLOCK(tipc_port_list_lock);
@@ -304,84 +301,3 @@ int tipc_withdraw(struct tipc_port *p_ptr, unsigned int scope,
 		p_ptr->published = 0;
 	return res;
 }
-
-int tipc_port_connect(u32 ref, struct tipc_portid const *peer)
-{
-	struct tipc_port *p_ptr;
-	int res;
-
-	p_ptr = tipc_port_lock(ref);
-	if (!p_ptr)
-		return -EINVAL;
-	res = __tipc_port_connect(ref, p_ptr, peer);
-	tipc_port_unlock(p_ptr);
-	return res;
-}
-
-/*
- * __tipc_port_connect - connect to a remote peer
- *
- * Port must be locked.
- */
-int __tipc_port_connect(u32 ref, struct tipc_port *p_ptr,
-			struct tipc_portid const *peer)
-{
-	struct tipc_msg *msg;
-	int res = -EINVAL;
-
-	if (p_ptr->published || p_ptr->connected)
-		goto exit;
-	if (!peer->ref)
-		goto exit;
-
-	msg = &p_ptr->phdr;
-	msg_set_destnode(msg, peer->node);
-	msg_set_destport(msg, peer->ref);
-	msg_set_type(msg, TIPC_CONN_MSG);
-	msg_set_lookup_scope(msg, 0);
-	msg_set_hdr_sz(msg, SHORT_H_SIZE);
-
-	p_ptr->probing_interval = PROBING_INTERVAL;
-	p_ptr->probing_state = TIPC_CONN_OK;
-	p_ptr->connected = 1;
-	k_start_timer(&p_ptr->timer, p_ptr->probing_interval);
-	res = tipc_node_add_conn(tipc_port_peernode(p_ptr), p_ptr->ref,
-				 tipc_port_peerport(p_ptr));
-exit:
-	p_ptr->max_pkt = tipc_node_get_mtu(peer->node, ref);
-	return res;
-}
-
-/*
- * __tipc_disconnect - disconnect port from peer
- *
- * Port must be locked.
- */
-int __tipc_port_disconnect(struct tipc_port *tp_ptr)
-{
-	if (tp_ptr->connected) {
-		tp_ptr->connected = 0;
-		/* let timer expire on it's own to avoid deadlock! */
-		tipc_node_remove_conn(tipc_port_peernode(tp_ptr), tp_ptr->ref);
-		return 0;
-	}
-
-	return -ENOTCONN;
-}
-
-/*
- * tipc_port_disconnect(): Disconnect port form peer.
- *                    This is a node local operation.
- */
-int tipc_port_disconnect(u32 ref)
-{
-	struct tipc_port *p_ptr;
-	int res;
-
-	p_ptr = tipc_port_lock(ref);
-	if (!p_ptr)
-		return -EINVAL;
-	res = __tipc_port_disconnect(p_ptr);
-	tipc_port_unlock(p_ptr);
-	return res;
-}
diff --git a/net/tipc/port.h b/net/tipc/port.h
index f5762f9..b356cb8 100644
--- a/net/tipc/port.h
+++ b/net/tipc/port.h
@@ -102,16 +102,6 @@ int tipc_publish(struct tipc_port *p_ptr, unsigned int scope,
 int tipc_withdraw(struct tipc_port *p_ptr, unsigned int scope,
 		  struct tipc_name_seq const *name_seq);
 
-int tipc_port_connect(u32 portref, struct tipc_portid const *port);
-
-int tipc_port_disconnect(u32 portref);
-
-/*
- * The following routines require that the port be locked on entry
- */
-int __tipc_port_disconnect(struct tipc_port *tp_ptr);
-int __tipc_port_connect(u32 ref, struct tipc_port *p_ptr,
-		   struct tipc_portid const *peer);
 int tipc_port_peer_msg(struct tipc_port *p_ptr, struct tipc_msg *msg);
 
 struct sk_buff *tipc_port_get_ports(void);
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index f202d47..a651058 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -45,6 +45,7 @@
 #define SS_READY	-2	/* socket is connectionless */
 
 #define CONN_TIMEOUT_DEFAULT	8000	/* default connect timeout = 8s */
+#define CONN_PROBING_INTERVAL 3600000	/* [ms] => 1 h */
 #define TIPC_FWD_MSG	        1
 
 static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb);
@@ -339,7 +340,9 @@ static int tipc_release(struct socket *sock)
 			if ((sock->state == SS_CONNECTING) ||
 			    (sock->state == SS_CONNECTED)) {
 				sock->state = SS_DISCONNECTING;
-				tipc_port_disconnect(port->ref);
+				port->connected = 0;
+				tipc_node_remove_conn(tipc_port_peernode(port),
+						      port->ref);
 			}
 			if (tipc_msg_reverse(buf, &dnode, TIPC_ERR_NO_PORT))
 				tipc_link_xmit(buf, dnode, 0);
@@ -988,29 +991,25 @@ static int tipc_send_packet(struct kiocb *iocb, struct socket *sock,
 	return tipc_send_stream(iocb, sock, m, dsz);
 }
 
-/**
- * auto_connect - complete connection setup to a remote port
- * @tsk: tipc socket structure
- * @msg: peer's response message
- *
- * Returns 0 on success, errno otherwise
+/* tipc_sk_finish_conn - complete the setup of a connection
  */
-static int auto_connect(struct tipc_sock *tsk, struct tipc_msg *msg)
+static void tipc_sk_finish_conn(struct tipc_port *port, u32 peer_port,
+				u32 peer_node)
 {
-	struct tipc_port *port = &tsk->port;
-	struct socket *sock = tsk->sk.sk_socket;
-	struct tipc_portid peer;
-
-	peer.ref = msg_origport(msg);
-	peer.node = msg_orignode(msg);
+	struct tipc_msg *msg = &port->phdr;
 
-	__tipc_port_connect(port->ref, port, &peer);
+	msg_set_destnode(msg, peer_node);
+	msg_set_destport(msg, peer_port);
+	msg_set_type(msg, TIPC_CONN_MSG);
+	msg_set_lookup_scope(msg, 0);
+	msg_set_hdr_sz(msg, SHORT_H_SIZE);
 
-	if (msg_importance(msg) > TIPC_CRITICAL_IMPORTANCE)
-		return -EINVAL;
-	msg_set_importance(&port->phdr, (u32)msg_importance(msg));
-	sock->state = SS_CONNECTED;
-	return 0;
+	port->probing_interval = CONN_PROBING_INTERVAL;
+	port->probing_state = TIPC_CONN_OK;
+	port->connected = 1;
+	k_start_timer(&port->timer, port->probing_interval);
+	tipc_node_add_conn(peer_node, port->ref, peer_port);
+	port->max_pkt = tipc_node_get_mtu(peer_node, port->ref);
 }
 
 /**
@@ -1405,7 +1404,6 @@ static int filter_connect(struct tipc_sock *tsk, struct sk_buff **buf)
 	struct tipc_msg *msg = buf_msg(*buf);
 
 	int retval = -TIPC_ERR_NO_PORT;
-	int res;
 
 	if (msg_mcast(msg))
 		return retval;
@@ -1416,13 +1414,20 @@ static int filter_connect(struct tipc_sock *tsk, struct sk_buff **buf)
 		if (msg_connected(msg) && tipc_port_peer_msg(port, msg)) {
 			if (unlikely(msg_errcode(msg))) {
 				sock->state = SS_DISCONNECTING;
-				__tipc_port_disconnect(port);
+				port->connected = 0;
+				/* let timer expire on it's own */
+				tipc_node_remove_conn(tipc_port_peernode(port),
+						      port->ref);
 			}
 			retval = TIPC_OK;
 		}
 		break;
 	case SS_CONNECTING:
 		/* Accept only ACK or NACK message */
+
+		if (unlikely(!msg_connected(msg)))
+			break;
+
 		if (unlikely(msg_errcode(msg))) {
 			sock->state = SS_DISCONNECTING;
 			sk->sk_err = ECONNREFUSED;
@@ -1430,17 +1435,17 @@ static int filter_connect(struct tipc_sock *tsk, struct sk_buff **buf)
 			break;
 		}
 
-		if (unlikely(!msg_connected(msg)))
-			break;
-
-		res = auto_connect(tsk, msg);
-		if (res) {
+		if (unlikely(msg_importance(msg) > TIPC_CRITICAL_IMPORTANCE)) {
 			sock->state = SS_DISCONNECTING;
-			sk->sk_err = -res;
+			sk->sk_err = EINVAL;
 			retval = TIPC_OK;
 			break;
 		}
 
+		tipc_sk_finish_conn(port, msg_origport(msg), msg_orignode(msg));
+		msg_set_importance(&port->phdr, msg_importance(msg));
+		sock->state = SS_CONNECTED;
+
 		/* If an incoming message is an 'ACK-', it should be
 		 * discarded here because it doesn't contain useful
 		 * data. In addition, we should try to wake up
@@ -1816,8 +1821,6 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags)
 	struct sk_buff *buf;
 	struct tipc_port *new_port;
 	struct tipc_msg *msg;
-	struct tipc_portid peer;
-	u32 new_ref;
 	long timeo;
 	int res;
 
@@ -1840,7 +1843,6 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags)
 
 	new_sk = new_sock->sk;
 	new_port = &tipc_sk(new_sk)->port;
-	new_ref = new_port->ref;
 	msg = buf_msg(buf);
 
 	/* we lock on new_sk; but lockdep sees the lock on sk */
@@ -1853,9 +1855,7 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags)
 	reject_rx_queue(new_sk);
 
 	/* Connect new socket to it's peer */
-	peer.ref = msg_origport(msg);
-	peer.node = msg_orignode(msg);
-	tipc_port_connect(new_ref, &peer);
+	tipc_sk_finish_conn(new_port, msg_origport(msg), msg_orignode(msg));
 	new_sock->state = SS_CONNECTED;
 
 	tipc_port_set_importance(new_port, msg_importance(msg));
@@ -1919,9 +1919,9 @@ restart:
 				kfree_skb(buf);
 				goto restart;
 			}
-			tipc_port_disconnect(port->ref);
 			if (tipc_msg_reverse(buf, &dnode, TIPC_CONN_SHUTDOWN))
 				tipc_link_xmit(buf, dnode, port->ref);
+			tipc_node_remove_conn(dnode, port->ref);
 		} else {
 			dnode = tipc_port_peernode(port);
 			buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE,
@@ -1930,11 +1930,10 @@ restart:
 					      tipc_port_peerport(port),
 					      port->ref, TIPC_CONN_SHUTDOWN);
 			tipc_link_xmit(buf, dnode, port->ref);
-			__tipc_port_disconnect(port);
 		}
-
+		port->connected = 0;
 		sock->state = SS_DISCONNECTING;
-
+		tipc_node_remove_conn(dnode, port->ref);
 		/* fall through */
 
 	case SS_DISCONNECTING:
-- 
1.7.9.5


------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH net-next 09/17] tipc: redefine message acknowledge function
  2014-08-22 22:09 [PATCH net-next 00/17] tipc: Merge port and socket layer code Jon Maloy
                   ` (7 preceding siblings ...)
  2014-08-22 22:09 ` [PATCH net-next 08/17] tipc: eliminate port_connect()/port_disconnect() functions Jon Maloy
@ 2014-08-22 22:09 ` Jon Maloy
  2014-08-22 22:09 ` [PATCH net-next 10/17] tipc: eliminate functions tipc_port_init and tipc_port_destroy Jon Maloy
                   ` (8 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Jon Maloy @ 2014-08-22 22:09 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, Paul Gortmaker, tipc-discussion

The function tipc_acknowledge() is a remnant from the obsolete native
API. Currently, it grabs port_lock, before building an acknowledge
message and sending it to the peer.

Since all access to socket members now is protected by the socket lock,
it has become unnecessary to grab port_lock here.

In this commit, we remove the usage of port_lock, simplify the
function, and move it to socket.c, renaming it to tipc_sk_send_ack().

Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Ying Xue <ying.xue@windriver.com>
---
 net/tipc/port.c   |   22 ----------------------
 net/tipc/port.h   |    2 --
 net/tipc/socket.c |   22 ++++++++++++++++++++--
 3 files changed, 20 insertions(+), 26 deletions(-)

diff --git a/net/tipc/port.c b/net/tipc/port.c
index 2f96719..1074ccb 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -221,28 +221,6 @@ void tipc_port_reinit(void)
 	spin_unlock_bh(&tipc_port_list_lock);
 }
 
-void tipc_acknowledge(u32 ref, u32 ack)
-{
-	struct tipc_port *p_ptr;
-	struct sk_buff *buf = NULL;
-	struct tipc_msg *msg;
-
-	p_ptr = tipc_port_lock(ref);
-	if (!p_ptr)
-		return;
-	if (p_ptr->connected)
-		buf = tipc_msg_create(CONN_MANAGER, CONN_ACK, INT_H_SIZE,
-				      0, tipc_port_peernode(p_ptr),
-				      tipc_own_addr, tipc_port_peerport(p_ptr),
-				      p_ptr->ref, TIPC_OK);
-	tipc_port_unlock(p_ptr);
-	if (!buf)
-		return;
-	msg = buf_msg(buf);
-	msg_set_msgcnt(msg, ack);
-	tipc_link_xmit(buf, msg_destnode(msg),	msg_link_selector(msg));
-}
-
 int tipc_publish(struct tipc_port *p_ptr, unsigned int scope,
 		 struct tipc_name_seq const *seq)
 {
diff --git a/net/tipc/port.h b/net/tipc/port.h
index b356cb8..c92e172 100644
--- a/net/tipc/port.h
+++ b/net/tipc/port.h
@@ -92,8 +92,6 @@ struct tipc_port_list;
 u32 tipc_port_init(struct tipc_port *p_ptr,
 		   const unsigned int importance);
 
-void tipc_acknowledge(u32 port_ref, u32 ack);
-
 void tipc_port_destroy(struct tipc_port *p_ptr);
 
 int tipc_publish(struct tipc_port *p_ptr, unsigned int scope,
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index a651058..686a11b 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -1106,6 +1106,24 @@ static int anc_data_recv(struct msghdr *m, struct tipc_msg *msg,
 	return 0;
 }
 
+static void tipc_sk_send_ack(struct tipc_port *port, uint ack)
+{
+	struct sk_buff *buf = NULL;
+	struct tipc_msg *msg;
+	u32 peer_port = tipc_port_peerport(port);
+	u32 dnode = tipc_port_peernode(port);
+
+	if (!port->connected)
+		return;
+	buf = tipc_msg_create(CONN_MANAGER, CONN_ACK, INT_H_SIZE, 0, dnode,
+			      tipc_own_addr, peer_port, port->ref, TIPC_OK);
+	if (!buf)
+		return;
+	msg = buf_msg(buf);
+	msg_set_msgcnt(msg, ack);
+	tipc_link_xmit(buf, dnode, msg_link_selector(msg));
+}
+
 static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop)
 {
 	struct sock *sk = sock->sk;
@@ -1226,7 +1244,7 @@ restart:
 	if (likely(!(flags & MSG_PEEK))) {
 		if ((sock->state != SS_READY) &&
 		    (++tsk->rcv_unacked >= TIPC_CONNACK_INTV)) {
-			tipc_acknowledge(port->ref, tsk->rcv_unacked);
+			tipc_sk_send_ack(port, tsk->rcv_unacked);
 			tsk->rcv_unacked = 0;
 		}
 		advance_rx_queue(sk);
@@ -1337,7 +1355,7 @@ restart:
 	/* Consume received message (optional) */
 	if (likely(!(flags & MSG_PEEK))) {
 		if (unlikely(++tsk->rcv_unacked >= TIPC_CONNACK_INTV)) {
-			tipc_acknowledge(port->ref, tsk->rcv_unacked);
+			tipc_sk_send_ack(port, tsk->rcv_unacked);
 			tsk->rcv_unacked = 0;
 		}
 		advance_rx_queue(sk);
-- 
1.7.9.5


------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH net-next 10/17] tipc: eliminate functions tipc_port_init and tipc_port_destroy
  2014-08-22 22:09 [PATCH net-next 00/17] tipc: Merge port and socket layer code Jon Maloy
                   ` (8 preceding siblings ...)
  2014-08-22 22:09 ` [PATCH net-next 09/17] tipc: redefine message acknowledge function Jon Maloy
@ 2014-08-22 22:09 ` Jon Maloy
  2014-08-22 22:09 ` [PATCH net-next 11/17] tipc: use registry when scanning sockets Jon Maloy
                   ` (7 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Jon Maloy @ 2014-08-22 22:09 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, Paul Gortmaker, tipc-discussion

After the latest changes to the socket/port layer the existence of
the functions tipc_port_init() and tipc_port_destroy() cannot be
justified. They are both called only once, from tipc_sk_create() and
tipc_sk_delete() respectively, and their functionality can better be
merged into the latter two functions.

This also entails that all remaining references to port_lock now are
made from inside socket.c, something that will make it easier to remove
this lock.

Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Ying Xue <ying.xue@windriver.com>
---
 net/tipc/port.c   |   75 ++---------------------------------------------------
 net/tipc/port.h   |    4 +--
 net/tipc/socket.c |   51 +++++++++++++++++++++++++++---------
 3 files changed, 42 insertions(+), 88 deletions(-)

diff --git a/net/tipc/port.c b/net/tipc/port.c
index 1074ccb..1efa298 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -42,10 +42,6 @@
 
 #define MAX_REJECT_SIZE 1024
 
-DEFINE_SPINLOCK(tipc_port_list_lock);
-
-static LIST_HEAD(ports);
-
 /**
  * tipc_port_peer_msg - verify message was sent by connected port's peer
  *
@@ -67,73 +63,6 @@ int tipc_port_peer_msg(struct tipc_port *p_ptr, struct tipc_msg *msg)
 		(!peernode && (orignode == tipc_own_addr));
 }
 
-/* tipc_port_init - intiate TIPC port and lock it
- *
- * Returns obtained reference if initialization is successful, zero otherwise
- */
-u32 tipc_port_init(struct tipc_port *p_ptr,
-		   const unsigned int importance)
-{
-	struct tipc_msg *msg;
-	u32 ref;
-
-	ref = tipc_ref_acquire(p_ptr, &p_ptr->lock);
-	if (!ref) {
-		pr_warn("Port registration failed, ref. table exhausted\n");
-		return 0;
-	}
-
-	p_ptr->max_pkt = MAX_PKT_DEFAULT;
-	p_ptr->ref = ref;
-	INIT_LIST_HEAD(&p_ptr->subscription.nodesub_list);
-	INIT_LIST_HEAD(&p_ptr->publications);
-	INIT_LIST_HEAD(&p_ptr->port_list);
-
-	/*
-	 * Must hold port list lock while initializing message header template
-	 * to ensure a change to node's own network address doesn't result
-	 * in template containing out-dated network address information
-	 */
-	spin_lock_bh(&tipc_port_list_lock);
-	msg = &p_ptr->phdr;
-	tipc_msg_init(msg, importance, TIPC_NAMED_MSG, NAMED_H_SIZE, 0);
-	msg_set_origport(msg, ref);
-	list_add_tail(&p_ptr->port_list, &ports);
-	spin_unlock_bh(&tipc_port_list_lock);
-	return ref;
-}
-
-void tipc_port_destroy(struct tipc_port *p_ptr)
-{
-	struct sk_buff *buf = NULL;
-	struct tipc_msg *msg = NULL;
-	u32 peer_node;
-
-	tipc_withdraw(p_ptr, 0, NULL);
-
-	spin_lock_bh(p_ptr->lock);
-	tipc_ref_discard(p_ptr->ref);
-	spin_unlock_bh(p_ptr->lock);
-
-	k_cancel_timer(&p_ptr->timer);
-	if (p_ptr->connected) {
-		peer_node = tipc_port_peernode(p_ptr);
-		buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG,
-				      SHORT_H_SIZE, 0, peer_node,
-				      tipc_own_addr, tipc_port_peerport(p_ptr),
-				      p_ptr->ref, TIPC_ERR_NO_PORT);
-		if (buf) {
-			msg = buf_msg(buf);
-			tipc_link_xmit(buf, peer_node, msg_link_selector(msg));
-		}
-		tipc_node_remove_conn(peer_node, p_ptr->ref);
-	}
-	spin_lock_bh(&tipc_port_list_lock);
-	list_del(&p_ptr->port_list);
-	spin_unlock_bh(&tipc_port_list_lock);
-	k_term_timer(&p_ptr->timer);
-}
-
 static int port_print(struct tipc_port *p_ptr, char *buf, int len, int full_id)
 {
 	struct publication *publ;
@@ -194,7 +123,7 @@ struct sk_buff *tipc_port_get_ports(void)
 	pb_len = ULTRA_STRING_MAX_LEN;
 
 	spin_lock_bh(&tipc_port_list_lock);
-	list_for_each_entry(p_ptr, &ports, port_list) {
+	list_for_each_entry(p_ptr, &tipc_socks, port_list) {
 		spin_lock_bh(p_ptr->lock);
 		str_len += port_print(p_ptr, pb, pb_len, 0);
 		spin_unlock_bh(p_ptr->lock);
@@ -213,7 +142,7 @@ void tipc_port_reinit(void)
 	struct tipc_msg *msg;
 
 	spin_lock_bh(&tipc_port_list_lock);
-	list_for_each_entry(p_ptr, &ports, port_list) {
+	list_for_each_entry(p_ptr, &tipc_socks, port_list) {
 		msg = &p_ptr->phdr;
 		msg_set_prevnode(msg, tipc_own_addr);
 		msg_set_orignode(msg, tipc_own_addr);
diff --git a/net/tipc/port.h b/net/tipc/port.h
index c92e172..4c6cfdd 100644
--- a/net/tipc/port.h
+++ b/net/tipc/port.h
@@ -63,7 +63,6 @@
  * @probing_state:
  * @probing_interval:
  * @timer_ref:
- * @subscription: "node down" subscription used to terminate failed connections
  */
 struct tipc_port {
 	spinlock_t *lock;
@@ -80,11 +79,10 @@ struct tipc_port {
 	u32 probing_state;
 	u32 probing_interval;
 	struct timer_list timer;
-	struct tipc_node_subscr subscription;
 };
 
+extern struct list_head tipc_socks;
 extern spinlock_t tipc_port_list_lock;
-struct tipc_port_list;
 
 /*
  * TIPC port manipulation routines
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 686a11b..f2be4c2 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -63,6 +63,9 @@ static const struct proto_ops msg_ops;
 static struct proto tipc_proto;
 static struct proto tipc_proto_kern;
 
+DEFINE_SPINLOCK(tipc_port_list_lock);
+LIST_HEAD(tipc_socks);
+
 /*
  * Revised TIPC socket locking policy:
  *
@@ -156,6 +159,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
 	struct sock *sk;
 	struct tipc_sock *tsk;
 	struct tipc_port *port;
+	struct tipc_msg *msg;
 	u32 ref;
 
 	/* Validate arguments */
@@ -191,18 +195,28 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
 
 	tsk = tipc_sk(sk);
 	port = &tsk->port;
-
-	ref = tipc_port_init(port, TIPC_LOW_IMPORTANCE);
+	ref = tipc_ref_acquire(port, &port->lock);
 	if (!ref) {
-		pr_warn("Socket registration failed, ref. table exhausted\n");
-		sk_free(sk);
+		pr_warn("Socket create failed; reference table exhausted\n");
 		return -ENOMEM;
 	}
+	port->max_pkt = MAX_PKT_DEFAULT;
+	port->ref = ref;
+	INIT_LIST_HEAD(&port->publications);
+	INIT_LIST_HEAD(&port->port_list);
+
+	/* Guard against race during node address update */
+	spin_lock_bh(&tipc_port_list_lock);
+	msg = &port->phdr;
+	tipc_msg_init(msg, TIPC_LOW_IMPORTANCE, TIPC_NAMED_MSG,
+		      NAMED_H_SIZE, 0);
+	msg_set_origport(msg, ref);
+	list_add_tail(&port->port_list, &tipc_socks);
+	spin_unlock_bh(&tipc_port_list_lock);
 
 	/* Finish initializing socket data structures */
 	sock->ops = ops;
 	sock->state = state;
-
 	sock_init_data(sock, sk);
 	k_init_timer(&port->timer, (Handler)tipc_sk_timeout, ref);
 	sk->sk_backlog_rcv = tipc_backlog_rcv;
@@ -330,6 +344,7 @@ static int tipc_release(struct socket *sock)
 	 * Reject all unreceived messages, except on an active connection
 	 * (which disconnects locally & sends a 'FIN+' to peer)
 	 */
+	dnode = tipc_port_peernode(port);
 	while (sock->state != SS_DISCONNECTING) {
 		buf = __skb_dequeue(&sk->sk_receive_queue);
 		if (buf == NULL)
@@ -341,18 +356,31 @@ static int tipc_release(struct socket *sock)
 			    (sock->state == SS_CONNECTED)) {
 				sock->state = SS_DISCONNECTING;
 				port->connected = 0;
-				tipc_node_remove_conn(tipc_port_peernode(port),
-						      port->ref);
+				tipc_node_remove_conn(dnode, port->ref);
 			}
 			if (tipc_msg_reverse(buf, &dnode, TIPC_ERR_NO_PORT))
 				tipc_link_xmit(buf, dnode, 0);
 		}
 	}
 
-	/* Destroy TIPC port; also disconnects an active connection and
-	 * sends a 'FIN-' to peer.
-	 */
-	tipc_port_destroy(port);
+	tipc_withdraw(port, 0, NULL);
+	spin_lock_bh(port->lock);
+	tipc_ref_discard(port->ref);
+	spin_unlock_bh(port->lock);
+	k_cancel_timer(&port->timer);
+	if (port->connected) {
+		buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG,
+				      SHORT_H_SIZE, 0, dnode, tipc_own_addr,
+				      tipc_port_peerport(port),
+				      port->ref, TIPC_ERR_NO_PORT);
+		if (buf)
+			tipc_link_xmit(buf, dnode, port->ref);
+		tipc_node_remove_conn(dnode, port->ref);
+	}
+	spin_lock_bh(&tipc_port_list_lock);
+	list_del(&port->port_list);
+	spin_unlock_bh(&tipc_port_list_lock);
+	k_term_timer(&port->timer);
 
 	/* Discard any remaining (connection-based) messages in receive queue */
 	__skb_queue_purge(&sk->sk_receive_queue);
@@ -360,7 +388,6 @@ static int tipc_release(struct socket *sock)
 	/* Reject any messages that accumulated in backlog queue */
 	sock->state = SS_DISCONNECTING;
 	release_sock(sk);
-
 	sock_put(sk);
 	sock->sk = NULL;
 
-- 
1.7.9.5


------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH net-next 11/17] tipc: use registry when scanning sockets
  2014-08-22 22:09 [PATCH net-next 00/17] tipc: Merge port and socket layer code Jon Maloy
                   ` (9 preceding siblings ...)
  2014-08-22 22:09 ` [PATCH net-next 10/17] tipc: eliminate functions tipc_port_init and tipc_port_destroy Jon Maloy
@ 2014-08-22 22:09 ` Jon Maloy
  2014-08-22 22:09 ` [PATCH net-next 12/17] tipc: replace port pointer with socket pointer in registry Jon Maloy
                   ` (6 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Jon Maloy @ 2014-08-22 22:09 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, Paul Gortmaker, tipc-discussion

The functions tipc_port_get_ports() and tipc_port_reinit() scan over
all sockets/ports to access each of them. This is done by using a
dedicated linked list, 'tipc_socks' where all sockets are members. The
list is in turn protected by a spinlock, 'port_list_lock', while each
socket is locked by using port_lock at the moment of access.

In order to reduce complexity and risk of deadlock, we want to get
rid of the linked list and the accompanying spinlock.

This is what we do in this commit. Instead of the linked list, we use
the port registry to scan across the sockets. We also add usage of
bh_lock_sock() inside the scope of port_lock in both functions, as a
preparation for the complete removal of port_lock.

Finally, we move the functions from port.c to socket.c, and rename them
to tipc_sk_sock_show() and tipc_sk_reinit() repectively.

Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Ying Xue <ying.xue@windriver.com>
---
 net/tipc/config.c |    4 +-
 net/tipc/net.c    |    2 +-
 net/tipc/port.c   |   87 ---------------------------------------
 net/tipc/port.h   |    5 ---
 net/tipc/ref.c    |   20 +++++++++
 net/tipc/ref.h    |    1 +
 net/tipc/socket.c |  118 ++++++++++++++++++++++++++++++++++++++++++++++++-----
 net/tipc/socket.h |    3 +-
 8 files changed, 133 insertions(+), 107 deletions(-)

diff --git a/net/tipc/config.c b/net/tipc/config.c
index 2b42403..876f4c6 100644
--- a/net/tipc/config.c
+++ b/net/tipc/config.c
@@ -35,7 +35,7 @@
  */
 
 #include "core.h"
-#include "port.h"
+#include "socket.h"
 #include "name_table.h"
 #include "config.h"
 #include "server.h"
@@ -266,7 +266,7 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
 		rep_tlv_buf = tipc_media_get_names();
 		break;
 	case TIPC_CMD_SHOW_PORTS:
-		rep_tlv_buf = tipc_port_get_ports();
+		rep_tlv_buf = tipc_sk_socks_show();
 		break;
 	case TIPC_CMD_SHOW_STATS:
 		rep_tlv_buf = tipc_show_stats();
diff --git a/net/tipc/net.c b/net/tipc/net.c
index 7fcc949..421dd89 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -111,7 +111,7 @@ int tipc_net_start(u32 addr)
 
 	tipc_own_addr = addr;
 	tipc_named_reinit();
-	tipc_port_reinit();
+	tipc_sk_reinit();
 	res = tipc_bclink_init();
 	if (res)
 		return res;
diff --git a/net/tipc/port.c b/net/tipc/port.c
index 1efa298..cea3730 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -63,93 +63,6 @@ int tipc_port_peer_msg(struct tipc_port *p_ptr, struct tipc_msg *msg)
 		(!peernode && (orignode == tipc_own_addr));
 }
 
-static int port_print(struct tipc_port *p_ptr, char *buf, int len, int full_id)
-{
-	struct publication *publ;
-	int ret;
-
-	if (full_id)
-		ret = tipc_snprintf(buf, len, "<%u.%u.%u:%u>:",
-				    tipc_zone(tipc_own_addr),
-				    tipc_cluster(tipc_own_addr),
-				    tipc_node(tipc_own_addr), p_ptr->ref);
-	else
-		ret = tipc_snprintf(buf, len, "%-10u:", p_ptr->ref);
-
-	if (p_ptr->connected) {
-		u32 dport = tipc_port_peerport(p_ptr);
-		u32 destnode = tipc_port_peernode(p_ptr);
-
-		ret += tipc_snprintf(buf + ret, len - ret,
-				     " connected to <%u.%u.%u:%u>",
-				     tipc_zone(destnode),
-				     tipc_cluster(destnode),
-				     tipc_node(destnode), dport);
-		if (p_ptr->conn_type != 0)
-			ret += tipc_snprintf(buf + ret, len - ret,
-					     " via {%u,%u}", p_ptr->conn_type,
-					     p_ptr->conn_instance);
-	} else if (p_ptr->published) {
-		ret += tipc_snprintf(buf + ret, len - ret, " bound to");
-		list_for_each_entry(publ, &p_ptr->publications, pport_list) {
-			if (publ->lower == publ->upper)
-				ret += tipc_snprintf(buf + ret, len - ret,
-						     " {%u,%u}", publ->type,
-						     publ->lower);
-			else
-				ret += tipc_snprintf(buf + ret, len - ret,
-						     " {%u,%u,%u}", publ->type,
-						     publ->lower, publ->upper);
-		}
-	}
-	ret += tipc_snprintf(buf + ret, len - ret, "\n");
-	return ret;
-}
-
-struct sk_buff *tipc_port_get_ports(void)
-{
-	struct sk_buff *buf;
-	struct tlv_desc *rep_tlv;
-	char *pb;
-	int pb_len;
-	struct tipc_port *p_ptr;
-	int str_len = 0;
-
-	buf = tipc_cfg_reply_alloc(TLV_SPACE(ULTRA_STRING_MAX_LEN));
-	if (!buf)
-		return NULL;
-	rep_tlv = (struct tlv_desc *)buf->data;
-	pb = TLV_DATA(rep_tlv);
-	pb_len = ULTRA_STRING_MAX_LEN;
-
-	spin_lock_bh(&tipc_port_list_lock);
-	list_for_each_entry(p_ptr, &tipc_socks, port_list) {
-		spin_lock_bh(p_ptr->lock);
-		str_len += port_print(p_ptr, pb, pb_len, 0);
-		spin_unlock_bh(p_ptr->lock);
-	}
-	spin_unlock_bh(&tipc_port_list_lock);
-	str_len += 1;	/* for "\0" */
-	skb_put(buf, TLV_SPACE(str_len));
-	TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len);
-
-	return buf;
-}
-
-void tipc_port_reinit(void)
-{
-	struct tipc_port *p_ptr;
-	struct tipc_msg *msg;
-
-	spin_lock_bh(&tipc_port_list_lock);
-	list_for_each_entry(p_ptr, &tipc_socks, port_list) {
-		msg = &p_ptr->phdr;
-		msg_set_prevnode(msg, tipc_own_addr);
-		msg_set_orignode(msg, tipc_own_addr);
-	}
-	spin_unlock_bh(&tipc_port_list_lock);
-}
-
 int tipc_publish(struct tipc_port *p_ptr, unsigned int scope,
 		 struct tipc_name_seq const *seq)
 {
diff --git a/net/tipc/port.h b/net/tipc/port.h
index 4c6cfdd..4a3c54e 100644
--- a/net/tipc/port.h
+++ b/net/tipc/port.h
@@ -73,7 +73,6 @@ struct tipc_port {
 	u32 max_pkt;
 	u32 ref;
 	struct tipc_msg phdr;
-	struct list_head port_list;
 	struct list_head publications;
 	u32 pub_count;
 	u32 probing_state;
@@ -81,9 +80,6 @@ struct tipc_port {
 	struct timer_list timer;
 };
 
-extern struct list_head tipc_socks;
-extern spinlock_t tipc_port_list_lock;
-
 /*
  * TIPC port manipulation routines
  */
@@ -100,7 +96,6 @@ int tipc_withdraw(struct tipc_port *p_ptr, unsigned int scope,
 
 int tipc_port_peer_msg(struct tipc_port *p_ptr, struct tipc_msg *msg);
 
-struct sk_buff *tipc_port_get_ports(void);
 void tipc_port_reinit(void);
 
 /**
diff --git a/net/tipc/ref.c b/net/tipc/ref.c
index 3d4ecd7..7fc2740 100644
--- a/net/tipc/ref.c
+++ b/net/tipc/ref.c
@@ -264,3 +264,23 @@ void *tipc_ref_lock(u32 ref)
 	}
 	return NULL;
 }
+
+/* tipc_ref_lock_next - lock & return next object after referenced one
+*/
+void *tipc_ref_lock_next(u32 *ref)
+{
+	struct reference *entry;
+	uint index = *ref & tipc_ref_table.index_mask;
+
+	while (++index < tipc_ref_table.capacity) {
+		entry = &tipc_ref_table.entries[index];
+		if (!entry->object)
+			continue;
+		spin_lock_bh(&entry->lock);
+		*ref = entry->ref;
+		if (entry->object)
+			return entry->object;
+		spin_unlock_bh(&entry->lock);
+	}
+	return NULL;
+}
diff --git a/net/tipc/ref.h b/net/tipc/ref.h
index d01aa1d..e236fa5 100644
--- a/net/tipc/ref.h
+++ b/net/tipc/ref.h
@@ -44,5 +44,6 @@ u32 tipc_ref_acquire(void *object, spinlock_t **lock);
 void tipc_ref_discard(u32 ref);
 
 void *tipc_ref_lock(u32 ref);
+void *tipc_ref_lock_next(u32 *ref);
 
 #endif
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index f2be4c2..ddc2f8c 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -40,6 +40,7 @@
 #include "node.h"
 #include "link.h"
 #include <linux/export.h>
+#include "config.h"
 
 #define SS_LISTENING	-1	/* socket is listening */
 #define SS_READY	-2	/* socket is connectionless */
@@ -63,9 +64,6 @@ static const struct proto_ops msg_ops;
 static struct proto tipc_proto;
 static struct proto tipc_proto_kern;
 
-DEFINE_SPINLOCK(tipc_port_list_lock);
-LIST_HEAD(tipc_socks);
-
 /*
  * Revised TIPC socket locking policy:
  *
@@ -113,6 +111,17 @@ LIST_HEAD(tipc_socks);
 
 #include "socket.h"
 
+/* tipc_sk_lock_next: find & lock next socket in registry from given port number
+*/
+static struct tipc_sock *tipc_sk_lock_next(u32 *ref)
+{
+	struct tipc_port *port = (struct tipc_port *)tipc_ref_lock_next(ref);
+
+	if (!port)
+		return NULL;
+	return tipc_port_to_sock(port);
+}
+
 /**
  * advance_rx_queue - discard first buffer in socket receive queue
  *
@@ -203,16 +212,11 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
 	port->max_pkt = MAX_PKT_DEFAULT;
 	port->ref = ref;
 	INIT_LIST_HEAD(&port->publications);
-	INIT_LIST_HEAD(&port->port_list);
 
-	/* Guard against race during node address update */
-	spin_lock_bh(&tipc_port_list_lock);
 	msg = &port->phdr;
 	tipc_msg_init(msg, TIPC_LOW_IMPORTANCE, TIPC_NAMED_MSG,
 		      NAMED_H_SIZE, 0);
 	msg_set_origport(msg, ref);
-	list_add_tail(&port->port_list, &tipc_socks);
-	spin_unlock_bh(&tipc_port_list_lock);
 
 	/* Finish initializing socket data structures */
 	sock->ops = ops;
@@ -377,9 +381,6 @@ static int tipc_release(struct socket *sock)
 			tipc_link_xmit(buf, dnode, port->ref);
 		tipc_node_remove_conn(dnode, port->ref);
 	}
-	spin_lock_bh(&tipc_port_list_lock);
-	list_del(&port->port_list);
-	spin_unlock_bh(&tipc_port_list_lock);
 	k_term_timer(&port->timer);
 
 	/* Discard any remaining (connection-based) messages in receive queue */
@@ -2043,6 +2044,101 @@ static void tipc_sk_timeout(unsigned long ref)
 	tipc_link_xmit(buf, msg_destnode(msg),	msg_link_selector(msg));
 }
 
+static int tipc_sk_show(struct tipc_port *port, char *buf,
+			int len, int full_id)
+{
+	struct publication *publ;
+	int ret;
+
+	if (full_id)
+		ret = tipc_snprintf(buf, len, "<%u.%u.%u:%u>:",
+				    tipc_zone(tipc_own_addr),
+				    tipc_cluster(tipc_own_addr),
+				    tipc_node(tipc_own_addr), port->ref);
+	else
+		ret = tipc_snprintf(buf, len, "%-10u:", port->ref);
+
+	if (port->connected) {
+		u32 dport = tipc_port_peerport(port);
+		u32 destnode = tipc_port_peernode(port);
+
+		ret += tipc_snprintf(buf + ret, len - ret,
+				     " connected to <%u.%u.%u:%u>",
+				     tipc_zone(destnode),
+				     tipc_cluster(destnode),
+				     tipc_node(destnode), dport);
+		if (port->conn_type != 0)
+			ret += tipc_snprintf(buf + ret, len - ret,
+					     " via {%u,%u}", port->conn_type,
+					     port->conn_instance);
+	} else if (port->published) {
+		ret += tipc_snprintf(buf + ret, len - ret, " bound to");
+		list_for_each_entry(publ, &port->publications, pport_list) {
+			if (publ->lower == publ->upper)
+				ret += tipc_snprintf(buf + ret, len - ret,
+						     " {%u,%u}", publ->type,
+						     publ->lower);
+			else
+				ret += tipc_snprintf(buf + ret, len - ret,
+						     " {%u,%u,%u}", publ->type,
+						     publ->lower, publ->upper);
+		}
+	}
+	ret += tipc_snprintf(buf + ret, len - ret, "\n");
+	return ret;
+}
+
+struct sk_buff *tipc_sk_socks_show(void)
+{
+	struct sk_buff *buf;
+	struct tlv_desc *rep_tlv;
+	char *pb;
+	int pb_len;
+	struct tipc_sock *tsk;
+	int str_len = 0;
+	u32 ref = 0;
+
+	buf = tipc_cfg_reply_alloc(TLV_SPACE(ULTRA_STRING_MAX_LEN));
+	if (!buf)
+		return NULL;
+	rep_tlv = (struct tlv_desc *)buf->data;
+	pb = TLV_DATA(rep_tlv);
+	pb_len = ULTRA_STRING_MAX_LEN;
+
+	tsk = tipc_sk_lock_next(&ref);
+	for (; tsk; tsk = tipc_sk_lock_next(&ref)) {
+		bh_lock_sock(&tsk->sk);
+		str_len += tipc_sk_show(&tsk->port, pb + str_len,
+					pb_len - str_len, 0);
+		bh_unlock_sock(&tsk->sk);
+		tipc_port_unlock(&tsk->port);
+	}
+	str_len += 1;	/* for "\0" */
+	skb_put(buf, TLV_SPACE(str_len));
+	TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len);
+
+	return buf;
+}
+
+/* tipc_sk_reinit: set non-zero address in all existing sockets
+ *                 when we go from standalone to network mode.
+ */
+void tipc_sk_reinit(void)
+{
+	struct tipc_msg *msg;
+	u32 ref = 0;
+	struct tipc_sock *tsk = tipc_sk_lock_next(&ref);
+
+	for (; tsk; tsk = tipc_sk_lock_next(&ref)) {
+		bh_lock_sock(&tsk->sk);
+		msg = &tsk->port.phdr;
+		msg_set_prevnode(msg, tipc_own_addr);
+		msg_set_orignode(msg, tipc_own_addr);
+		bh_unlock_sock(&tsk->sk);
+		tipc_port_unlock(&tsk->port);
+	}
+}
+
 /**
  * tipc_setsockopt - set socket option
  * @sock: socket structure
diff --git a/net/tipc/socket.h b/net/tipc/socket.h
index 1405633..5d515be 100644
--- a/net/tipc/socket.h
+++ b/net/tipc/socket.h
@@ -79,7 +79,8 @@ static inline int tipc_sk_conn_cong(struct tipc_sock *tsk)
 }
 
 int tipc_sk_rcv(struct sk_buff *buf);
-
+struct sk_buff *tipc_sk_socks_show(void);
 void tipc_sk_mcast_rcv(struct sk_buff *buf);
+void tipc_sk_reinit(void);
 
 #endif
-- 
1.7.9.5


------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH net-next 12/17] tipc: replace port pointer with socket pointer in registry
  2014-08-22 22:09 [PATCH net-next 00/17] tipc: Merge port and socket layer code Jon Maloy
                   ` (10 preceding siblings ...)
  2014-08-22 22:09 ` [PATCH net-next 11/17] tipc: use registry when scanning sockets Jon Maloy
@ 2014-08-22 22:09 ` Jon Maloy
  2014-08-22 22:09 ` [PATCH net-next 13/17] tipc: remove port_lock Jon Maloy
                   ` (5 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Jon Maloy @ 2014-08-22 22:09 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, Paul Gortmaker, tipc-discussion

In order to make tipc_sock the only entity referencable from other
parts of the stack, we add a tipc_sock pointer instead of a tipc_port
pointer to the registry. As a consequence, we also let the function
tipc_port_lock() return a pointer to a tipc_sock instead  of a tipc_port.
We keep the function's name for now, since the lock still is owned by
the port.

This is another step in the direction of eliminating port_lock, replacing
its usage with lock_sock() and bh_lock_sock().

Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Ying Xue <ying.xue@windriver.com>
---
 net/tipc/port.h   |    4 ++--
 net/tipc/socket.c |   23 +++++++++--------------
 2 files changed, 11 insertions(+), 16 deletions(-)

diff --git a/net/tipc/port.h b/net/tipc/port.h
index 4a3c54e..33e52fe 100644
--- a/net/tipc/port.h
+++ b/net/tipc/port.h
@@ -101,9 +101,9 @@ void tipc_port_reinit(void);
 /**
  * tipc_port_lock - lock port instance referred to and return its pointer
  */
-static inline struct tipc_port *tipc_port_lock(u32 ref)
+static inline struct tipc_sock *tipc_port_lock(u32 ref)
 {
-	return (struct tipc_port *)tipc_ref_lock(ref);
+	return (struct tipc_sock *)tipc_ref_lock(ref);
 }
 
 /**
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index ddc2f8c..247f245 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -115,11 +115,7 @@ static struct proto tipc_proto_kern;
 */
 static struct tipc_sock *tipc_sk_lock_next(u32 *ref)
 {
-	struct tipc_port *port = (struct tipc_port *)tipc_ref_lock_next(ref);
-
-	if (!port)
-		return NULL;
-	return tipc_port_to_sock(port);
+	return (struct tipc_sock *)tipc_ref_lock_next(ref);
 }
 
 /**
@@ -204,7 +200,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
 
 	tsk = tipc_sk(sk);
 	port = &tsk->port;
-	ref = tipc_ref_acquire(port, &port->lock);
+	ref = tipc_ref_acquire(tsk, &port->lock);
 	if (!ref) {
 		pr_warn("Socket create failed; reference table exhausted\n");
 		return -ENOMEM;
@@ -1655,13 +1651,12 @@ int tipc_sk_rcv(struct sk_buff *buf)
 	u32 dnode;
 
 	/* Validate destination and message */
-	port = tipc_port_lock(dport);
-	if (unlikely(!port)) {
+	tsk = tipc_port_lock(dport);
+	if (unlikely(!tsk)) {
 		rc = tipc_msg_eval(buf, &dnode);
 		goto exit;
 	}
-
-	tsk = tipc_port_to_sock(port);
+	port = &tsk->port;
 	sk = &tsk->sk;
 
 	/* Queue message */
@@ -2002,21 +1997,21 @@ restart:
 
 static void tipc_sk_timeout(unsigned long ref)
 {
-	struct tipc_port *port = tipc_port_lock(ref);
-	struct tipc_sock *tsk;
+	struct tipc_sock *tsk = tipc_port_lock(ref);
+	struct tipc_port *port;
 	struct sock *sk;
 	struct sk_buff *buf = NULL;
 	struct tipc_msg *msg = NULL;
 	u32 peer_port, peer_node;
 
-	if (!port)
+	if (!tsk)
 		return;
 
+	port = &tsk->port;
 	if (!port->connected) {
 		tipc_port_unlock(port);
 		return;
 	}
-	tsk = tipc_port_to_sock(port);
 	sk = &tsk->sk;
 	bh_lock_sock(sk);
 	peer_port = tipc_port_peerport(port);
-- 
1.7.9.5


------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH net-next 13/17] tipc: remove port_lock
  2014-08-22 22:09 [PATCH net-next 00/17] tipc: Merge port and socket layer code Jon Maloy
                   ` (11 preceding siblings ...)
  2014-08-22 22:09 ` [PATCH net-next 12/17] tipc: replace port pointer with socket pointer in registry Jon Maloy
@ 2014-08-22 22:09 ` Jon Maloy
  2014-08-22 22:09 ` [PATCH net-next 14/17] tipc: remove source file port.c Jon Maloy
                   ` (4 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Jon Maloy @ 2014-08-22 22:09 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, Paul Gortmaker, tipc-discussion

In previous commits we have reduced usage of port_lock to a minimum,
and complemented it with usage of bh_lock_sock() at the remaining
locations. The purpose has been to remove this lock altogether, since
it largely duplicates the role of bh_lock_sock. We are now ready to do
this.

However, we still need to protect the BH callers from inadvertent
release of the socket while they hold a reference to it. We do this by
replacing port_lock by a combination of a rw-lock protecting the
reference table as such, and updating the socket reference counter while
the socket is referenced from BH. This technique is more standard and
comprehensible than the previous approach, and turns out to have a
positive effect on overall performance.

Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Ying Xue <ying.xue@windriver.com>
---
 net/tipc/port.h   |   20 -------
 net/tipc/ref.c    |  158 ++++++++++++++++++++++++-----------------------------
 net/tipc/ref.h    |   15 +++--
 net/tipc/socket.c |   64 +++++++++-------------
 4 files changed, 108 insertions(+), 149 deletions(-)

diff --git a/net/tipc/port.h b/net/tipc/port.h
index 33e52fe..38bf8cb 100644
--- a/net/tipc/port.h
+++ b/net/tipc/port.h
@@ -37,7 +37,6 @@
 #ifndef _TIPC_PORT_H
 #define _TIPC_PORT_H
 
-#include "ref.h"
 #include "net.h"
 #include "msg.h"
 #include "node_subscr.h"
@@ -65,7 +64,6 @@
  * @timer_ref:
  */
 struct tipc_port {
-	spinlock_t *lock;
 	int connected;
 	u32 conn_type;
 	u32 conn_instance;
@@ -98,24 +96,6 @@ int tipc_port_peer_msg(struct tipc_port *p_ptr, struct tipc_msg *msg);
 
 void tipc_port_reinit(void);
 
-/**
- * tipc_port_lock - lock port instance referred to and return its pointer
- */
-static inline struct tipc_sock *tipc_port_lock(u32 ref)
-{
-	return (struct tipc_sock *)tipc_ref_lock(ref);
-}
-
-/**
- * tipc_port_unlock - unlock a port instance
- *
- * Can use pointer instead of tipc_ref_unlock() since port is already locked.
- */
-static inline void tipc_port_unlock(struct tipc_port *p_ptr)
-{
-	spin_unlock_bh(p_ptr->lock);
-}
-
 static inline u32 tipc_port_peernode(struct tipc_port *p_ptr)
 {
 	return msg_destnode(&p_ptr->phdr);
diff --git a/net/tipc/ref.c b/net/tipc/ref.c
index 7fc2740..ea981be 100644
--- a/net/tipc/ref.c
+++ b/net/tipc/ref.c
@@ -1,7 +1,7 @@
 /*
- * net/tipc/ref.c: TIPC object registry code
+ * net/tipc/ref.c: TIPC socket registry code
  *
- * Copyright (c) 1991-2006, Ericsson AB
+ * Copyright (c) 1991-2006, 2014, Ericsson AB
  * Copyright (c) 2004-2007, Wind River Systems
  * All rights reserved.
  *
@@ -38,24 +38,22 @@
 #include "ref.h"
 
 /**
- * struct reference - TIPC object reference entry
- * @object: pointer to object associated with reference entry
- * @lock: spinlock controlling access to object
- * @ref: reference value for object (combines instance & array index info)
+ * struct reference - TIPC socket reference entry
+ * @tsk: pointer to socket associated with reference entry
+ * @ref: reference value for socket (combines instance & array index info)
  */
 struct reference {
-	void *object;
-	spinlock_t lock;
+	struct tipc_sock *tsk;
 	u32 ref;
 };
 
 /**
- * struct tipc_ref_table - table of TIPC object reference entries
+ * struct tipc_ref_table - table of TIPC socket reference entries
  * @entries: pointer to array of reference entries
  * @capacity: array index of first unusable entry
  * @init_point: array index of first uninitialized entry
- * @first_free: array index of first unused object reference entry
- * @last_free: array index of last unused object reference entry
+ * @first_free: array index of first unused socket reference entry
+ * @last_free: array index of last unused socket reference entry
  * @index_mask: bitmask for array index portion of reference values
  * @start_mask: initial value for instance value portion of reference values
  */
@@ -70,9 +68,9 @@ struct ref_table {
 };
 
 /*
- * Object reference table consists of 2**N entries.
+ * Socket reference table consists of 2**N entries.
  *
- * State	Object ptr	Reference
+ * State	Socket ptr	Reference
  * -----        ----------      ---------
  * In use        non-NULL       XXXX|own index
  *				(XXXX changes each time entry is acquired)
@@ -89,10 +87,10 @@ struct ref_table {
 
 static struct ref_table tipc_ref_table;
 
-static DEFINE_SPINLOCK(ref_table_lock);
+static DEFINE_RWLOCK(ref_table_lock);
 
 /**
- * tipc_ref_table_init - create reference table for objects
+ * tipc_ref_table_init - create reference table for sockets
  */
 int tipc_ref_table_init(u32 requested_size, u32 start)
 {
@@ -122,84 +120,69 @@ int tipc_ref_table_init(u32 requested_size, u32 start)
 }
 
 /**
- * tipc_ref_table_stop - destroy reference table for objects
+ * tipc_ref_table_stop - destroy reference table for sockets
  */
 void tipc_ref_table_stop(void)
 {
+	if (!tipc_ref_table.entries)
+		return;
 	vfree(tipc_ref_table.entries);
 	tipc_ref_table.entries = NULL;
 }
 
-/**
- * tipc_ref_acquire - create reference to an object
+/* tipc_ref_acquire - create reference to a socket
  *
- * Register an object pointer in reference table and lock the object.
+ * Register an socket pointer in the reference table.
  * Returns a unique reference value that is used from then on to retrieve the
- * object pointer, or to determine that the object has been deregistered.
- *
- * Note: The object is returned in the locked state so that the caller can
- * register a partially initialized object, without running the risk that
- * the object will be accessed before initialization is complete.
+ * socket pointer, or to determine if the socket has been deregistered.
  */
-u32 tipc_ref_acquire(void *object, spinlock_t **lock)
+u32 tipc_ref_acquire(struct tipc_sock *tsk)
 {
 	u32 index;
 	u32 index_mask;
 	u32 next_plus_upper;
-	u32 ref;
-	struct reference *entry = NULL;
+	u32 ref = 0;
+	struct reference *entry;
 
-	if (!object) {
+	if (unlikely(!tsk)) {
 		pr_err("Attempt to acquire ref. to non-existent obj\n");
 		return 0;
 	}
-	if (!tipc_ref_table.entries) {
+	if (unlikely(!tipc_ref_table.entries)) {
 		pr_err("Ref. table not found in acquisition attempt\n");
 		return 0;
 	}
 
-	/* take a free entry, if available; otherwise initialize a new entry */
-	spin_lock_bh(&ref_table_lock);
-	if (tipc_ref_table.first_free) {
+	/* Take a free entry, if available; otherwise initialize a new one */
+	write_lock_bh(&ref_table_lock);
+	index = tipc_ref_table.first_free;
+	entry = &tipc_ref_table.entries[index];
+
+	if (likely(index)) {
 		index = tipc_ref_table.first_free;
 		entry = &(tipc_ref_table.entries[index]);
 		index_mask = tipc_ref_table.index_mask;
 		next_plus_upper = entry->ref;
 		tipc_ref_table.first_free = next_plus_upper & index_mask;
 		ref = (next_plus_upper & ~index_mask) + index;
+		entry->tsk = tsk;
 	} else if (tipc_ref_table.init_point < tipc_ref_table.capacity) {
 		index = tipc_ref_table.init_point++;
 		entry = &(tipc_ref_table.entries[index]);
-		spin_lock_init(&entry->lock);
 		ref = tipc_ref_table.start_mask + index;
-	} else {
-		ref = 0;
 	}
-	spin_unlock_bh(&ref_table_lock);
 
-	/*
-	 * Grab the lock so no one else can modify this entry
-	 * While we assign its ref value & object pointer
-	 */
-	if (entry) {
-		spin_lock_bh(&entry->lock);
+	if (ref) {
 		entry->ref = ref;
-		entry->object = object;
-		*lock = &entry->lock;
-		/*
-		 * keep it locked, the caller is responsible
-		 * for unlocking this when they're done with it
-		 */
+		entry->tsk = tsk;
 	}
-
+	write_unlock_bh(&ref_table_lock);
 	return ref;
 }
 
-/**
- * tipc_ref_discard - invalidate references to an object
+/* tipc_ref_discard - invalidate reference to an socket
  *
- * Disallow future references to an object and free up the entry for re-use.
- * Note: The entry's spin_lock may still be busy after discard
+ * Disallow future references to an socket and free up the entry for re-use.
  */
 void tipc_ref_discard(u32 ref)
 {
@@ -207,7 +190,7 @@ void tipc_ref_discard(u32 ref)
 	u32 index;
 	u32 index_mask;
 
-	if (!tipc_ref_table.entries) {
+	if (unlikely(!tipc_ref_table.entries)) {
 		pr_err("Ref. table not found during discard attempt\n");
 		return;
 	}
@@ -216,71 +199,72 @@ void tipc_ref_discard(u32 ref)
 	index = ref & index_mask;
 	entry = &(tipc_ref_table.entries[index]);
 
-	spin_lock_bh(&ref_table_lock);
+	write_lock_bh(&ref_table_lock);
 
-	if (!entry->object) {
-		pr_err("Attempt to discard ref. to non-existent obj\n");
+	if (unlikely(!entry->tsk)) {
+		pr_err("Attempt to discard ref. to non-existent socket\n");
 		goto exit;
 	}
-	if (entry->ref != ref) {
+	if (unlikely(entry->ref != ref)) {
 		pr_err("Attempt to discard non-existent reference\n");
 		goto exit;
 	}
 
 	/*
-	 * mark entry as unused; increment instance part of entry's reference
+	 * Mark entry as unused; increment instance part of entry's reference
 	 * to invalidate any subsequent references
 	 */
-	entry->object = NULL;
+	entry->tsk = NULL;
 	entry->ref = (ref & ~index_mask) + (index_mask + 1);
 
-	/* append entry to free entry list */
-	if (tipc_ref_table.first_free == 0)
+	/* Append entry to free entry list */
+	if (unlikely(tipc_ref_table.first_free == 0))
 		tipc_ref_table.first_free = index;
 	else
 		tipc_ref_table.entries[tipc_ref_table.last_free].ref |= index;
 	tipc_ref_table.last_free = index;
-
 exit:
-	spin_unlock_bh(&ref_table_lock);
+	write_unlock_bh(&ref_table_lock);
 }
 
-/**
- * tipc_ref_lock - lock referenced object and return pointer to it
+/* tipc_sk_get - find referenced socket and return pointer to it
  */
-void *tipc_ref_lock(u32 ref)
+struct tipc_sock *tipc_sk_get(u32 ref)
 {
-	if (likely(tipc_ref_table.entries)) {
-		struct reference *entry;
+	struct reference *entry;
+	struct tipc_sock *tsk;
 
-		entry = &tipc_ref_table.entries[ref &
-						tipc_ref_table.index_mask];
-		if (likely(entry->ref != 0)) {
-			spin_lock_bh(&entry->lock);
-			if (likely((entry->ref == ref) && (entry->object)))
-				return entry->object;
-			spin_unlock_bh(&entry->lock);
-		}
-	}
-	return NULL;
+	if (unlikely(!tipc_ref_table.entries))
+		return NULL;
+	read_lock_bh(&ref_table_lock);
+	entry = &tipc_ref_table.entries[ref & tipc_ref_table.index_mask];
+	tsk = entry->tsk;
+	if (likely(tsk && (entry->ref == ref)))
+		sock_hold(&tsk->sk);
+	else
+		tsk = NULL;
+	read_unlock_bh(&ref_table_lock);
+	return tsk;
 }
 
-/* tipc_ref_lock_next - lock & return next object after referenced one
+/* tipc_sk_get_next - lock & return next socket after referenced one
 */
-void *tipc_ref_lock_next(u32 *ref)
+struct tipc_sock *tipc_sk_get_next(u32 *ref)
 {
 	struct reference *entry;
+	struct tipc_sock *tsk = NULL;
 	uint index = *ref & tipc_ref_table.index_mask;
 
+	read_lock_bh(&ref_table_lock);
 	while (++index < tipc_ref_table.capacity) {
 		entry = &tipc_ref_table.entries[index];
-		if (!entry->object)
+		if (!entry->tsk)
 			continue;
-		spin_lock_bh(&entry->lock);
+		tsk = entry->tsk;
+		sock_hold(&tsk->sk);
 		*ref = entry->ref;
-		if (entry->object)
-			return entry->object;
-		spin_unlock_bh(&entry->lock);
+		break;
 	}
-	return NULL;
+	read_unlock_bh(&ref_table_lock);
+	return tsk;
 }
diff --git a/net/tipc/ref.h b/net/tipc/ref.h
index e236fa5..2b75a89 100644
--- a/net/tipc/ref.h
+++ b/net/tipc/ref.h
@@ -1,7 +1,7 @@
 /*
  * net/tipc/ref.h: Include file for TIPC object registry code
  *
- * Copyright (c) 1991-2006, Ericsson AB
+ * Copyright (c) 1991-2006, 2014, Ericsson AB
  * Copyright (c) 2005-2006, Wind River Systems
  * All rights reserved.
  *
@@ -37,13 +37,20 @@
 #ifndef _TIPC_REF_H
 #define _TIPC_REF_H
 
+#include "socket.h"
+
 int tipc_ref_table_init(u32 requested_size, u32 start);
 void tipc_ref_table_stop(void);
 
-u32 tipc_ref_acquire(void *object, spinlock_t **lock);
+u32 tipc_ref_acquire(struct tipc_sock *tsk);
 void tipc_ref_discard(u32 ref);
 
-void *tipc_ref_lock(u32 ref);
-void *tipc_ref_lock_next(u32 *ref);
+struct tipc_sock *tipc_sk_get(u32 ref);
+struct tipc_sock *tipc_sk_get_next(u32 *ref);
+
+static inline void tipc_sk_put(struct tipc_sock *tsk)
+{
+	sock_put(&tsk->sk);
+}
 
 #endif
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 247f245..7e6240e 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -35,6 +35,7 @@
  */
 
 #include "core.h"
+#include "ref.h"
 #include "port.h"
 #include "name_table.h"
 #include "node.h"
@@ -111,13 +112,6 @@ static struct proto tipc_proto_kern;
 
 #include "socket.h"
 
-/* tipc_sk_lock_next: find & lock next socket in registry from given port number
-*/
-static struct tipc_sock *tipc_sk_lock_next(u32 *ref)
-{
-	return (struct tipc_sock *)tipc_ref_lock_next(ref);
-}
-
 /**
  * advance_rx_queue - discard first buffer in socket receive queue
  *
@@ -200,7 +194,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
 
 	tsk = tipc_sk(sk);
 	port = &tsk->port;
-	ref = tipc_ref_acquire(tsk, &port->lock);
+	ref = tipc_ref_acquire(tsk);
 	if (!ref) {
 		pr_warn("Socket create failed; reference table exhausted\n");
 		return -ENOMEM;
@@ -226,7 +220,6 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
 	tsk->conn_timeout = CONN_TIMEOUT_DEFAULT;
 	tsk->sent_unacked = 0;
 	atomic_set(&tsk->dupl_rcvcnt, 0);
-	tipc_port_unlock(port);
 
 	if (sock->state == SS_READY) {
 		tipc_port_set_unreturnable(port, true);
@@ -364,9 +357,7 @@ static int tipc_release(struct socket *sock)
 	}
 
 	tipc_withdraw(port, 0, NULL);
-	spin_lock_bh(port->lock);
 	tipc_ref_discard(port->ref);
-	spin_unlock_bh(port->lock);
 	k_cancel_timer(&port->timer);
 	if (port->connected) {
 		buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG,
@@ -1651,7 +1642,7 @@ int tipc_sk_rcv(struct sk_buff *buf)
 	u32 dnode;
 
 	/* Validate destination and message */
-	tsk = tipc_port_lock(dport);
+	tsk = tipc_sk_get(dport);
 	if (unlikely(!tsk)) {
 		rc = tipc_msg_eval(buf, &dnode);
 		goto exit;
@@ -1672,8 +1663,7 @@ int tipc_sk_rcv(struct sk_buff *buf)
 			rc = -TIPC_ERR_OVERLOAD;
 	}
 	bh_unlock_sock(sk);
-	tipc_port_unlock(port);
-
+	tipc_sk_put(tsk);
 	if (likely(!rc))
 		return 0;
 exit:
@@ -1997,23 +1987,23 @@ restart:
 
 static void tipc_sk_timeout(unsigned long ref)
 {
-	struct tipc_sock *tsk = tipc_port_lock(ref);
+	struct tipc_sock *tsk;
 	struct tipc_port *port;
 	struct sock *sk;
 	struct sk_buff *buf = NULL;
-	struct tipc_msg *msg = NULL;
 	u32 peer_port, peer_node;
 
+	tsk = tipc_sk_get(ref);
 	if (!tsk)
-		return;
-
+		goto exit;
+	sk = &tsk->sk;
 	port = &tsk->port;
+
+	bh_lock_sock(sk);
 	if (!port->connected) {
-		tipc_port_unlock(port);
-		return;
+		bh_unlock_sock(sk);
+		goto exit;
 	}
-	sk = &tsk->sk;
-	bh_lock_sock(sk);
 	peer_port = tipc_port_peerport(port);
 	peer_node = tipc_port_peernode(port);
 
@@ -2031,12 +2021,10 @@ static void tipc_sk_timeout(unsigned long ref)
 		k_start_timer(&port->timer, port->probing_interval);
 	}
 	bh_unlock_sock(sk);
-	tipc_port_unlock(port);
-	if (!buf)
-		return;
-
-	msg = buf_msg(buf);
-	tipc_link_xmit(buf, msg_destnode(msg),	msg_link_selector(msg));
+	if (buf)
+		tipc_link_xmit(buf, peer_node, ref);
+exit:
+	tipc_sk_put(tsk);
 }
 
 static int tipc_sk_show(struct tipc_port *port, char *buf,
@@ -2100,13 +2088,13 @@ struct sk_buff *tipc_sk_socks_show(void)
 	pb = TLV_DATA(rep_tlv);
 	pb_len = ULTRA_STRING_MAX_LEN;
 
-	tsk = tipc_sk_lock_next(&ref);
-	for (; tsk; tsk = tipc_sk_lock_next(&ref)) {
-		bh_lock_sock(&tsk->sk);
+	tsk = tipc_sk_get_next(&ref);
+	for (; tsk; tsk = tipc_sk_get_next(&ref)) {
+		lock_sock(&tsk->sk);
 		str_len += tipc_sk_show(&tsk->port, pb + str_len,
 					pb_len - str_len, 0);
-		bh_unlock_sock(&tsk->sk);
-		tipc_port_unlock(&tsk->port);
+		release_sock(&tsk->sk);
+		tipc_sk_put(tsk);
 	}
 	str_len += 1;	/* for "\0" */
 	skb_put(buf, TLV_SPACE(str_len));
@@ -2122,15 +2110,15 @@ void tipc_sk_reinit(void)
 {
 	struct tipc_msg *msg;
 	u32 ref = 0;
-	struct tipc_sock *tsk = tipc_sk_lock_next(&ref);
+	struct tipc_sock *tsk = tipc_sk_get_next(&ref);
 
-	for (; tsk; tsk = tipc_sk_lock_next(&ref)) {
-		bh_lock_sock(&tsk->sk);
+	for (; tsk; tsk = tipc_sk_get_next(&ref)) {
+		lock_sock(&tsk->sk);
 		msg = &tsk->port.phdr;
 		msg_set_prevnode(msg, tipc_own_addr);
 		msg_set_orignode(msg, tipc_own_addr);
-		bh_unlock_sock(&tsk->sk);
-		tipc_port_unlock(&tsk->port);
+		release_sock(&tsk->sk);
+		tipc_sk_put(tsk);
 	}
 }
 
-- 
1.7.9.5


------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH net-next 14/17] tipc: remove source file port.c
  2014-08-22 22:09 [PATCH net-next 00/17] tipc: Merge port and socket layer code Jon Maloy
                   ` (12 preceding siblings ...)
  2014-08-22 22:09 ` [PATCH net-next 13/17] tipc: remove port_lock Jon Maloy
@ 2014-08-22 22:09 ` Jon Maloy
  2014-08-22 22:09 ` [PATCH net-next 15/17] tipc: remove include file port.h Jon Maloy
                   ` (3 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Jon Maloy @ 2014-08-22 22:09 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, Paul Gortmaker, tipc-discussion

In this commit, we move the remaining functions in port.c to
socket.c, and give them new names that correspond to their new
location. We then remove the file port.c.

There are only cosmetic changes to the moved functions.

Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Ying Xue <ying.xue@windriver.com>
---
 net/tipc/Makefile |    2 +-
 net/tipc/port.c   |  123 -----------------------------------------------------
 net/tipc/socket.c |  102 +++++++++++++++++++++++++++++++++++++++++---
 3 files changed, 97 insertions(+), 130 deletions(-)
 delete mode 100644 net/tipc/port.c

diff --git a/net/tipc/Makefile b/net/tipc/Makefile
index a080c66..5206a44 100644
--- a/net/tipc/Makefile
+++ b/net/tipc/Makefile
@@ -7,7 +7,7 @@ obj-$(CONFIG_TIPC) := tipc.o
 tipc-y	+= addr.o bcast.o bearer.o config.o \
 	   core.o link.o discover.o msg.o  \
 	   name_distr.o  subscr.o name_table.o net.o  \
-	   netlink.o node.o node_subscr.o port.o ref.o  \
+	   netlink.o node.o node_subscr.o ref.o  \
 	   socket.o log.o eth_media.o server.o
 
 tipc-$(CONFIG_TIPC_MEDIA_IB)	+= ib_media.o
diff --git a/net/tipc/port.c b/net/tipc/port.c
deleted file mode 100644
index cea3730..0000000
--- a/net/tipc/port.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * net/tipc/port.c: TIPC port code
- *
- * Copyright (c) 1992-2007, 2014, Ericsson AB
- * Copyright (c) 2004-2008, 2010-2013, Wind River Systems
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the names of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "core.h"
-#include "config.h"
-#include "port.h"
-#include "name_table.h"
-#include "socket.h"
-
-#define MAX_REJECT_SIZE 1024
-
-/**
- * tipc_port_peer_msg - verify message was sent by connected port's peer
- *
- * Handles cases where the node's network address has changed from
- * the default of <0.0.0> to its configured setting.
- */
-int tipc_port_peer_msg(struct tipc_port *p_ptr, struct tipc_msg *msg)
-{
-	u32 peernode;
-	u32 orignode;
-
-	if (msg_origport(msg) != tipc_port_peerport(p_ptr))
-		return 0;
-
-	orignode = msg_orignode(msg);
-	peernode = tipc_port_peernode(p_ptr);
-	return (orignode == peernode) ||
-		(!orignode && (peernode == tipc_own_addr)) ||
-		(!peernode && (orignode == tipc_own_addr));
-}
-
-int tipc_publish(struct tipc_port *p_ptr, unsigned int scope,
-		 struct tipc_name_seq const *seq)
-{
-	struct publication *publ;
-	u32 key;
-
-	if (p_ptr->connected)
-		return -EINVAL;
-	key = p_ptr->ref + p_ptr->pub_count + 1;
-	if (key == p_ptr->ref)
-		return -EADDRINUSE;
-
-	publ = tipc_nametbl_publish(seq->type, seq->lower, seq->upper,
-				    scope, p_ptr->ref, key);
-	if (publ) {
-		list_add(&publ->pport_list, &p_ptr->publications);
-		p_ptr->pub_count++;
-		p_ptr->published = 1;
-		return 0;
-	}
-	return -EINVAL;
-}
-
-int tipc_withdraw(struct tipc_port *p_ptr, unsigned int scope,
-		  struct tipc_name_seq const *seq)
-{
-	struct publication *publ;
-	struct publication *tpubl;
-	int res = -EINVAL;
-
-	if (!seq) {
-		list_for_each_entry_safe(publ, tpubl,
-					 &p_ptr->publications, pport_list) {
-			tipc_nametbl_withdraw(publ->type, publ->lower,
-					      publ->ref, publ->key);
-		}
-		res = 0;
-	} else {
-		list_for_each_entry_safe(publ, tpubl,
-					 &p_ptr->publications, pport_list) {
-			if (publ->scope != scope)
-				continue;
-			if (publ->type != seq->type)
-				continue;
-			if (publ->lower != seq->lower)
-				continue;
-			if (publ->upper != seq->upper)
-				break;
-			tipc_nametbl_withdraw(publ->type, publ->lower,
-					      publ->ref, publ->key);
-			res = 0;
-			break;
-		}
-	}
-	if (list_empty(&p_ptr->publications))
-		p_ptr->published = 0;
-	return res;
-}
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 7e6240e..ea33eab 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -57,6 +57,10 @@ static int tipc_release(struct socket *sock);
 static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags);
 static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p);
 static void tipc_sk_timeout(unsigned long ref);
+static int tipc_sk_publish(struct tipc_port *port, uint scope,
+			   struct tipc_name_seq const *seq);
+static int tipc_sk_withdraw(struct tipc_port *port, uint scope,
+			    struct tipc_name_seq const *seq);
 
 static const struct proto_ops packet_ops;
 static const struct proto_ops stream_ops;
@@ -138,6 +142,38 @@ static void reject_rx_queue(struct sock *sk)
 	}
 }
 
+/* tipc_sk_peer_msg - verify if message was sent by connected port's peer
+ *
+ * Handles cases where the node's network address has changed from
+ * the default of <0.0.0> to its configured setting.
+ */
+static bool tipc_sk_peer_msg(struct tipc_sock *tsk, struct tipc_msg *msg)
+{
+	u32 peer_port = tipc_port_peerport(&tsk->port);
+	u32 orig_node;
+	u32 peer_node;
+
+	if (unlikely(!tsk->port.connected))
+		return false;
+
+	if (unlikely(msg_origport(msg) != peer_port))
+		return false;
+
+	orig_node = msg_orignode(msg);
+	peer_node = tipc_port_peernode(&tsk->port);
+
+	if (likely(orig_node == peer_node))
+		return true;
+
+	if (!orig_node && (peer_node == tipc_own_addr))
+		return true;
+
+	if (!peer_node && (orig_node == tipc_own_addr))
+		return true;
+
+	return false;
+}
+
 /**
  * tipc_sk_create - create a TIPC socket
  * @net: network namespace (must be default network)
@@ -356,7 +392,7 @@ static int tipc_release(struct socket *sock)
 		}
 	}
 
-	tipc_withdraw(port, 0, NULL);
+	tipc_sk_withdraw(port, 0, NULL);
 	tipc_ref_discard(port->ref);
 	k_cancel_timer(&port->timer);
 	if (port->connected) {
@@ -407,7 +443,7 @@ static int tipc_bind(struct socket *sock, struct sockaddr *uaddr,
 
 	lock_sock(sk);
 	if (unlikely(!uaddr_len)) {
-		res = tipc_withdraw(&tsk->port, 0, NULL);
+		res = tipc_sk_withdraw(&tsk->port, 0, NULL);
 		goto exit;
 	}
 
@@ -435,8 +471,8 @@ static int tipc_bind(struct socket *sock, struct sockaddr *uaddr,
 	}
 
 	res = (addr->scope > 0) ?
-		tipc_publish(&tsk->port, addr->scope, &addr->addr.nameseq) :
-		tipc_withdraw(&tsk->port, -addr->scope, &addr->addr.nameseq);
+		tipc_sk_publish(&tsk->port, addr->scope, &addr->addr.nameseq) :
+		tipc_sk_withdraw(&tsk->port, -addr->scope, &addr->addr.nameseq);
 exit:
 	release_sock(sk);
 	return res;
@@ -663,7 +699,7 @@ static int tipc_sk_proto_rcv(struct tipc_sock *tsk, u32 *dnode,
 	int conn_cong;
 
 	/* Ignore if connection cannot be validated: */
-	if (!port->connected || !tipc_port_peer_msg(port, msg))
+	if (!tipc_sk_peer_msg(tsk, msg))
 		goto exit;
 
 	port->probing_state = TIPC_CONN_OK;
@@ -1444,7 +1480,7 @@ static int filter_connect(struct tipc_sock *tsk, struct sk_buff **buf)
 	switch ((int)sock->state) {
 	case SS_CONNECTED:
 		/* Accept only connection-based messages sent by peer */
-		if (msg_connected(msg) && tipc_port_peer_msg(port, msg)) {
+		if (tipc_sk_peer_msg(tsk, msg)) {
 			if (unlikely(msg_errcode(msg))) {
 				sock->state = SS_DISCONNECTING;
 				port->connected = 0;
@@ -2027,6 +2063,60 @@ exit:
 	tipc_sk_put(tsk);
 }
 
+static int tipc_sk_publish(struct tipc_port *port, uint scope,
+			   struct tipc_name_seq const *seq)
+{
+	struct publication *publ;
+	u32 key;
+
+	if (port->connected)
+		return -EINVAL;
+	key = port->ref + port->pub_count + 1;
+	if (key == port->ref)
+		return -EADDRINUSE;
+
+	publ = tipc_nametbl_publish(seq->type, seq->lower, seq->upper,
+				    scope, port->ref, key);
+	if (unlikely(!publ))
+		return -EINVAL;
+
+	list_add(&publ->pport_list, &port->publications);
+	port->pub_count++;
+	port->published = 1;
+	return 0;
+}
+
+static int tipc_sk_withdraw(struct tipc_port *port, uint scope,
+			    struct tipc_name_seq const *seq)
+{
+	struct publication *publ;
+	struct publication *safe;
+	int rc = -EINVAL;
+
+	list_for_each_entry_safe(publ, safe, &port->publications, pport_list) {
+		if (seq) {
+			if (publ->scope != scope)
+				continue;
+			if (publ->type != seq->type)
+				continue;
+			if (publ->lower != seq->lower)
+				continue;
+			if (publ->upper != seq->upper)
+				break;
+			tipc_nametbl_withdraw(publ->type, publ->lower,
+					      publ->ref, publ->key);
+			rc = 0;
+			break;
+		}
+		tipc_nametbl_withdraw(publ->type, publ->lower,
+				      publ->ref, publ->key);
+		rc = 0;
+	}
+	if (list_empty(&port->publications))
+		port->published = 0;
+	return rc;
+}
+
 static int tipc_sk_show(struct tipc_port *port, char *buf,
 			int len, int full_id)
 {
-- 
1.7.9.5


------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH net-next 15/17] tipc: remove include file port.h
  2014-08-22 22:09 [PATCH net-next 00/17] tipc: Merge port and socket layer code Jon Maloy
                   ` (13 preceding siblings ...)
  2014-08-22 22:09 ` [PATCH net-next 14/17] tipc: remove source file port.c Jon Maloy
@ 2014-08-22 22:09 ` Jon Maloy
  2014-08-22 22:09 ` [PATCH net-next 16/17] tipc: remove files ref.h and ref.c Jon Maloy
                   ` (2 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Jon Maloy @ 2014-08-22 22:09 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, Paul Gortmaker, tipc-discussion

We move the inline functions in the file port.h to socket.c, and modify
their names accordingly.

We move struct tipc_port and some macros to socket.h.

Finally, we remove the file port.h.

Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Ying Xue <ying.xue@windriver.com>
---
 net/tipc/bcast.c      |    1 -
 net/tipc/core.c       |    2 +-
 net/tipc/link.c       |    1 -
 net/tipc/name_table.c |    1 -
 net/tipc/net.c        |    1 -
 net/tipc/port.h       |  145 -------------------------------------------------
 net/tipc/socket.c     |  123 +++++++++++++++++++++++++++--------------
 net/tipc/socket.h     |   39 ++++++++++++-
 net/tipc/subscr.c     |    1 -
 9 files changed, 121 insertions(+), 193 deletions(-)
 delete mode 100644 net/tipc/port.h

diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 9510fb2..b2bbe69 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -37,7 +37,6 @@
 
 #include "core.h"
 #include "link.h"
-#include "port.h"
 #include "socket.h"
 #include "msg.h"
 #include "bcast.h"
diff --git a/net/tipc/core.c b/net/tipc/core.c
index 676d180..b3b03ef 100644
--- a/net/tipc/core.c
+++ b/net/tipc/core.c
@@ -39,7 +39,7 @@
 #include "name_table.h"
 #include "subscr.h"
 #include "config.h"
-#include "port.h"
+#include "socket.h"
 
 #include <linux/module.h>
 
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 6c775a1..65410e1 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -36,7 +36,6 @@
 
 #include "core.h"
 #include "link.h"
-#include "port.h"
 #include "socket.h"
 #include "name_distr.h"
 #include "discover.h"
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 9d7d37d..c058e30 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -39,7 +39,6 @@
 #include "name_table.h"
 #include "name_distr.h"
 #include "subscr.h"
-#include "port.h"
 
 #define TIPC_NAMETBL_SIZE 1024		/* must be a power of 2 */
 
diff --git a/net/tipc/net.c b/net/tipc/net.c
index 421dd89..93b9944 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -38,7 +38,6 @@
 #include "net.h"
 #include "name_distr.h"
 #include "subscr.h"
-#include "port.h"
 #include "socket.h"
 #include "node.h"
 #include "config.h"
diff --git a/net/tipc/port.h b/net/tipc/port.h
deleted file mode 100644
index 38bf8cb..0000000
--- a/net/tipc/port.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * net/tipc/port.h: Include file for TIPC port code
- *
- * Copyright (c) 1994-2007, 2014, Ericsson AB
- * Copyright (c) 2004-2007, 2010-2013, Wind River Systems
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the names of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _TIPC_PORT_H
-#define _TIPC_PORT_H
-
-#include "net.h"
-#include "msg.h"
-#include "node_subscr.h"
-
-#define TIPC_CONNACK_INTV         256
-#define TIPC_FLOWCTRL_WIN        (TIPC_CONNACK_INTV * 2)
-#define TIPC_CONN_OVERLOAD_LIMIT ((TIPC_FLOWCTRL_WIN * 2 + 1) * \
-				  SKB_TRUESIZE(TIPC_MAX_USER_MSG_SIZE))
-
-/**
- * struct tipc_port - TIPC port structure
- * @lock: pointer to spinlock for controlling access to port
- * @connected: non-zero if port is currently connected to a peer port
- * @conn_type: TIPC type used when connection was established
- * @conn_instance: TIPC instance used when connection was established
- * @published: non-zero if port has one or more associated names
- * @max_pkt: maximum packet size "hint" used when building messages sent by port
- * @ref: unique reference to port in TIPC object registry
- * @phdr: preformatted message header used when sending messages
- * @port_list: adjacent ports in TIPC's global list of ports
- * @publications: list of publications for port
- * @pub_count: total # of publications port has made during its lifetime
- * @probing_state:
- * @probing_interval:
- * @timer_ref:
- */
-struct tipc_port {
-	int connected;
-	u32 conn_type;
-	u32 conn_instance;
-	int published;
-	u32 max_pkt;
-	u32 ref;
-	struct tipc_msg phdr;
-	struct list_head publications;
-	u32 pub_count;
-	u32 probing_state;
-	u32 probing_interval;
-	struct timer_list timer;
-};
-
-/*
- * TIPC port manipulation routines
- */
-u32 tipc_port_init(struct tipc_port *p_ptr,
-		   const unsigned int importance);
-
-void tipc_port_destroy(struct tipc_port *p_ptr);
-
-int tipc_publish(struct tipc_port *p_ptr, unsigned int scope,
-		 struct tipc_name_seq const *name_seq);
-
-int tipc_withdraw(struct tipc_port *p_ptr, unsigned int scope,
-		  struct tipc_name_seq const *name_seq);
-
-int tipc_port_peer_msg(struct tipc_port *p_ptr, struct tipc_msg *msg);
-
-void tipc_port_reinit(void);
-
-static inline u32 tipc_port_peernode(struct tipc_port *p_ptr)
-{
-	return msg_destnode(&p_ptr->phdr);
-}
-
-static inline u32 tipc_port_peerport(struct tipc_port *p_ptr)
-{
-	return msg_destport(&p_ptr->phdr);
-}
-
-static inline  bool tipc_port_unreliable(struct tipc_port *port)
-{
-	return msg_src_droppable(&port->phdr) != 0;
-}
-
-static inline void tipc_port_set_unreliable(struct tipc_port *port,
-					    bool unreliable)
-{
-	msg_set_src_droppable(&port->phdr, unreliable ? 1 : 0);
-}
-
-static inline bool tipc_port_unreturnable(struct tipc_port *port)
-{
-	return msg_dest_droppable(&port->phdr) != 0;
-}
-
-static inline void tipc_port_set_unreturnable(struct tipc_port *port,
-					     bool unreturnable)
-{
-	msg_set_dest_droppable(&port->phdr, unreturnable ? 1 : 0);
-}
-
-
-static inline int tipc_port_importance(struct tipc_port *port)
-{
-	return msg_importance(&port->phdr);
-}
-
-static inline int tipc_port_set_importance(struct tipc_port *port, int imp)
-{
-	if (imp > TIPC_CRITICAL_IMPORTANCE)
-		return -EINVAL;
-	msg_set_importance(&port->phdr, (u32)imp);
-	return 0;
-}
-
-#endif
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index ea33eab..70eacea 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -36,12 +36,12 @@
 
 #include "core.h"
 #include "ref.h"
-#include "port.h"
 #include "name_table.h"
 #include "node.h"
 #include "link.h"
 #include <linux/export.h>
 #include "config.h"
+#include "socket.h"
 
 #define SS_LISTENING	-1	/* socket is listening */
 #define SS_READY	-2	/* socket is connectionless */
@@ -114,24 +114,65 @@ static struct proto tipc_proto_kern;
  *   - port reference
  */
 
-#include "socket.h"
+static u32 tsk_peer_node(struct tipc_port *p_ptr)
+{
+	return msg_destnode(&p_ptr->phdr);
+}
+
+static u32 tsk_peer_port(struct tipc_port *p_ptr)
+{
+	return msg_destport(&p_ptr->phdr);
+}
+
+static  bool tsk_unreliable(struct tipc_port *port)
+{
+	return msg_src_droppable(&port->phdr) != 0;
+}
+
+static void tsk_set_unreliable(struct tipc_port *port, bool unreliable)
+{
+	msg_set_src_droppable(&port->phdr, unreliable ? 1 : 0);
+}
+
+static bool tsk_unreturnable(struct tipc_port *port)
+{
+	return msg_dest_droppable(&port->phdr) != 0;
+}
+
+static void tsk_set_unreturnable(struct tipc_port *port, bool unreturnable)
+{
+	msg_set_dest_droppable(&port->phdr, unreturnable ? 1 : 0);
+}
+
+static int tsk_importance(struct tipc_port *port)
+{
+	return msg_importance(&port->phdr);
+}
+
+static int tsk_set_importance(struct tipc_port *port, int imp)
+{
+	if (imp > TIPC_CRITICAL_IMPORTANCE)
+		return -EINVAL;
+	msg_set_importance(&port->phdr, (u32)imp);
+	return 0;
+}
 
 /**
- * advance_rx_queue - discard first buffer in socket receive queue
+ * tsk_advance_rx_queue - discard first buffer in socket receive queue
  *
  * Caller must hold socket lock
  */
-static void advance_rx_queue(struct sock *sk)
+static void tsk_advance_rx_queue(struct sock *sk)
 {
 	kfree_skb(__skb_dequeue(&sk->sk_receive_queue));
 }
 
 /**
- * reject_rx_queue - reject all buffers in socket receive queue
+ * tsk_rej_rx_queue - reject all buffers in socket receive queue
  *
  * Caller must hold socket lock
  */
-static void reject_rx_queue(struct sock *sk)
+static void tsk_rej_rx_queue(struct sock *sk)
 {
 	struct sk_buff *buf;
 	u32 dnode;
@@ -142,14 +183,14 @@ static void reject_rx_queue(struct sock *sk)
 	}
 }
 
-/* tipc_sk_peer_msg - verify if message was sent by connected port's peer
+/* tsk_peer_msg - verify if message was sent by connected port's peer
  *
  * Handles cases where the node's network address has changed from
  * the default of <0.0.0> to its configured setting.
  */
-static bool tipc_sk_peer_msg(struct tipc_sock *tsk, struct tipc_msg *msg)
+static bool tsk_peer_msg(struct tipc_sock *tsk, struct tipc_msg *msg)
 {
-	u32 peer_port = tipc_port_peerport(&tsk->port);
+	u32 peer_port = tsk_peer_port(&tsk->port);
 	u32 orig_node;
 	u32 peer_node;
 
@@ -160,7 +201,7 @@ static bool tipc_sk_peer_msg(struct tipc_sock *tsk, struct tipc_msg *msg)
 		return false;
 
 	orig_node = msg_orignode(msg);
-	peer_node = tipc_port_peernode(&tsk->port);
+	peer_node = tsk_peer_node(&tsk->port);
 
 	if (likely(orig_node == peer_node))
 		return true;
@@ -258,9 +299,9 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
 	atomic_set(&tsk->dupl_rcvcnt, 0);
 
 	if (sock->state == SS_READY) {
-		tipc_port_set_unreturnable(port, true);
+		tsk_set_unreturnable(port, true);
 		if (sock->type == SOCK_DGRAM)
-			tipc_port_set_unreliable(port, true);
+			tsk_set_unreliable(port, true);
 	}
 	return 0;
 }
@@ -373,7 +414,7 @@ static int tipc_release(struct socket *sock)
 	 * Reject all unreceived messages, except on an active connection
 	 * (which disconnects locally & sends a 'FIN+' to peer)
 	 */
-	dnode = tipc_port_peernode(port);
+	dnode = tsk_peer_node(port);
 	while (sock->state != SS_DISCONNECTING) {
 		buf = __skb_dequeue(&sk->sk_receive_queue);
 		if (buf == NULL)
@@ -398,7 +439,7 @@ static int tipc_release(struct socket *sock)
 	if (port->connected) {
 		buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG,
 				      SHORT_H_SIZE, 0, dnode, tipc_own_addr,
-				      tipc_port_peerport(port),
+				      tsk_peer_port(port),
 				      port->ref, TIPC_ERR_NO_PORT);
 		if (buf)
 			tipc_link_xmit(buf, dnode, port->ref);
@@ -502,8 +543,8 @@ static int tipc_getname(struct socket *sock, struct sockaddr *uaddr,
 		if ((sock->state != SS_CONNECTED) &&
 			((peer != 2) || (sock->state != SS_DISCONNECTING)))
 			return -ENOTCONN;
-		addr->addr.id.ref = tipc_port_peerport(&tsk->port);
-		addr->addr.id.node = tipc_port_peernode(&tsk->port);
+		addr->addr.id.ref = tsk_peer_port(&tsk->port);
+		addr->addr.id.node = tsk_peer_node(&tsk->port);
 	} else {
 		addr->addr.id.ref = tsk->port.ref;
 		addr->addr.id.node = tipc_own_addr;
@@ -699,7 +740,7 @@ static int tipc_sk_proto_rcv(struct tipc_sock *tsk, u32 *dnode,
 	int conn_cong;
 
 	/* Ignore if connection cannot be validated: */
-	if (!tipc_sk_peer_msg(tsk, msg))
+	if (!tsk_peer_msg(tsk, msg))
 		goto exit;
 
 	port->probing_state = TIPC_CONN_OK;
@@ -986,7 +1027,7 @@ static int tipc_send_stream(struct kiocb *iocb, struct socket *sock,
 	}
 
 	timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT);
-	dnode = tipc_port_peernode(port);
+	dnode = tsk_peer_node(port);
 
 next:
 	mtu = port->max_pkt;
@@ -1161,8 +1202,8 @@ static void tipc_sk_send_ack(struct tipc_port *port, uint ack)
 {
 	struct sk_buff *buf = NULL;
 	struct tipc_msg *msg;
-	u32 peer_port = tipc_port_peerport(port);
-	u32 dnode = tipc_port_peernode(port);
+	u32 peer_port = tsk_peer_port(port);
+	u32 dnode = tsk_peer_node(port);
 
 	if (!port->connected)
 		return;
@@ -1260,7 +1301,7 @@ restart:
 
 	/* Discard an empty non-errored message & try again */
 	if ((!sz) && (!err)) {
-		advance_rx_queue(sk);
+		tsk_advance_rx_queue(sk);
 		goto restart;
 	}
 
@@ -1298,7 +1339,7 @@ restart:
 			tipc_sk_send_ack(port, tsk->rcv_unacked);
 			tsk->rcv_unacked = 0;
 		}
-		advance_rx_queue(sk);
+		tsk_advance_rx_queue(sk);
 	}
 exit:
 	release_sock(sk);
@@ -1360,7 +1401,7 @@ restart:
 
 	/* Discard an empty non-errored message & try again */
 	if ((!sz) && (!err)) {
-		advance_rx_queue(sk);
+		tsk_advance_rx_queue(sk);
 		goto restart;
 	}
 
@@ -1409,7 +1450,7 @@ restart:
 			tipc_sk_send_ack(port, tsk->rcv_unacked);
 			tsk->rcv_unacked = 0;
 		}
-		advance_rx_queue(sk);
+		tsk_advance_rx_queue(sk);
 	}
 
 	/* Loop around if more data is required */
@@ -1480,12 +1521,12 @@ static int filter_connect(struct tipc_sock *tsk, struct sk_buff **buf)
 	switch ((int)sock->state) {
 	case SS_CONNECTED:
 		/* Accept only connection-based messages sent by peer */
-		if (tipc_sk_peer_msg(tsk, msg)) {
+		if (tsk_peer_msg(tsk, msg)) {
 			if (unlikely(msg_errcode(msg))) {
 				sock->state = SS_DISCONNECTING;
 				port->connected = 0;
 				/* let timer expire on it's own */
-				tipc_node_remove_conn(tipc_port_peernode(port),
+				tipc_node_remove_conn(tsk_peer_node(port),
 						      port->ref);
 			}
 			retval = TIPC_OK;
@@ -1919,13 +1960,13 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags)
 	 * Reject any stray messages received by new socket
 	 * before the socket lock was taken (very, very unlikely)
 	 */
-	reject_rx_queue(new_sk);
+	tsk_rej_rx_queue(new_sk);
 
 	/* Connect new socket to it's peer */
 	tipc_sk_finish_conn(new_port, msg_origport(msg), msg_orignode(msg));
 	new_sock->state = SS_CONNECTED;
 
-	tipc_port_set_importance(new_port, msg_importance(msg));
+	tsk_set_importance(new_port, msg_importance(msg));
 	if (msg_named(msg)) {
 		new_port->conn_type = msg_nametype(msg);
 		new_port->conn_instance = msg_nameinst(msg);
@@ -1938,7 +1979,7 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags)
 	if (!msg_data_sz(msg)) {
 		struct msghdr m = {NULL,};
 
-		advance_rx_queue(sk);
+		tsk_advance_rx_queue(sk);
 		tipc_send_packet(NULL, new_sock, &m, 0);
 	} else {
 		__skb_dequeue(&sk->sk_receive_queue);
@@ -1990,11 +2031,11 @@ restart:
 				tipc_link_xmit(buf, dnode, port->ref);
 			tipc_node_remove_conn(dnode, port->ref);
 		} else {
-			dnode = tipc_port_peernode(port);
+			dnode = tsk_peer_node(port);
 			buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE,
 					      TIPC_CONN_MSG, SHORT_H_SIZE,
 					      0, dnode, tipc_own_addr,
-					      tipc_port_peerport(port),
+					      tsk_peer_port(port),
 					      port->ref, TIPC_CONN_SHUTDOWN);
 			tipc_link_xmit(buf, dnode, port->ref);
 		}
@@ -2040,8 +2081,8 @@ static void tipc_sk_timeout(unsigned long ref)
 		bh_unlock_sock(sk);
 		goto exit;
 	}
-	peer_port = tipc_port_peerport(port);
-	peer_node = tipc_port_peernode(port);
+	peer_port = tsk_peer_port(port);
+	peer_node = tsk_peer_node(port);
 
 	if (port->probing_state == TIPC_CONN_PROBING) {
 		/* Previous probe not answered -> self abort */
@@ -2132,8 +2173,8 @@ static int tipc_sk_show(struct tipc_port *port, char *buf,
 		ret = tipc_snprintf(buf, len, "%-10u:", port->ref);
 
 	if (port->connected) {
-		u32 dport = tipc_port_peerport(port);
-		u32 destnode = tipc_port_peernode(port);
+		u32 dport = tsk_peer_port(port);
+		u32 destnode = tsk_peer_node(port);
 
 		ret += tipc_snprintf(buf + ret, len - ret,
 				     " connected to <%u.%u.%u:%u>",
@@ -2248,16 +2289,16 @@ static int tipc_setsockopt(struct socket *sock, int lvl, int opt,
 
 	switch (opt) {
 	case TIPC_IMPORTANCE:
-		res = tipc_port_set_importance(port, value);
+		res = tsk_set_importance(port, value);
 		break;
 	case TIPC_SRC_DROPPABLE:
 		if (sock->type != SOCK_STREAM)
-			tipc_port_set_unreliable(port, value);
+			tsk_set_unreliable(port, value);
 		else
 			res = -ENOPROTOOPT;
 		break;
 	case TIPC_DEST_DROPPABLE:
-		tipc_port_set_unreturnable(port, value);
+		tsk_set_unreturnable(port, value);
 		break;
 	case TIPC_CONN_TIMEOUT:
 		tipc_sk(sk)->conn_timeout = value;
@@ -2307,13 +2348,13 @@ static int tipc_getsockopt(struct socket *sock, int lvl, int opt,
 
 	switch (opt) {
 	case TIPC_IMPORTANCE:
-		value = tipc_port_importance(port);
+		value = tsk_importance(port);
 		break;
 	case TIPC_SRC_DROPPABLE:
-		value = tipc_port_unreliable(port);
+		value = tsk_unreliable(port);
 		break;
 	case TIPC_DEST_DROPPABLE:
-		value = tipc_port_unreturnable(port);
+		value = tsk_unreturnable(port);
 		break;
 	case TIPC_CONN_TIMEOUT:
 		value = tipc_sk(sk)->conn_timeout;
diff --git a/net/tipc/socket.h b/net/tipc/socket.h
index 5d515be..b98725e 100644
--- a/net/tipc/socket.h
+++ b/net/tipc/socket.h
@@ -35,11 +35,48 @@
 #ifndef _TIPC_SOCK_H
 #define _TIPC_SOCK_H
 
-#include "port.h"
 #include <net/sock.h>
+#include "msg.h"
 
 #define TIPC_CONN_OK      0
 #define TIPC_CONN_PROBING 1
+#define TIPC_CONNACK_INTV         256
+#define TIPC_FLOWCTRL_WIN        (TIPC_CONNACK_INTV * 2)
+#define TIPC_CONN_OVERLOAD_LIMIT ((TIPC_FLOWCTRL_WIN * 2 + 1) * \
+				  SKB_TRUESIZE(TIPC_MAX_USER_MSG_SIZE))
+
+/**
+ * struct tipc_port - TIPC port structure
+ * @lock: pointer to spinlock for controlling access to port
+ * @connected: non-zero if port is currently connected to a peer port
+ * @conn_type: TIPC type used when connection was established
+ * @conn_instance: TIPC instance used when connection was established
+ * @published: non-zero if port has one or more associated names
+ * @max_pkt: maximum packet size "hint" used when building messages sent by port
+ * @ref: unique reference to port in TIPC object registry
+ * @phdr: preformatted message header used when sending messages
+ * @port_list: adjacent ports in TIPC's global list of ports
+ * @publications: list of publications for port
+ * @pub_count: total # of publications port has made during its lifetime
+ * @probing_state:
+ * @probing_interval:
+ * @timer_ref:
+ */
+struct tipc_port {
+	int connected;
+	u32 conn_type;
+	u32 conn_instance;
+	int published;
+	u32 max_pkt;
+	u32 ref;
+	struct tipc_msg phdr;
+	struct list_head port_list;
+	struct list_head publications;
+	u32 pub_count;
+	u32 probing_state;
+	u32 probing_interval;
+	struct timer_list timer;
+};
 
 /**
  * struct tipc_sock - TIPC socket structure
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c
index 6424372..31b5cb2 100644
--- a/net/tipc/subscr.c
+++ b/net/tipc/subscr.c
@@ -36,7 +36,6 @@
 
 #include "core.h"
 #include "name_table.h"
-#include "port.h"
 #include "subscr.h"
 
 /**
-- 
1.7.9.5


------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH net-next 16/17] tipc: remove files ref.h and ref.c
  2014-08-22 22:09 [PATCH net-next 00/17] tipc: Merge port and socket layer code Jon Maloy
                   ` (14 preceding siblings ...)
  2014-08-22 22:09 ` [PATCH net-next 15/17] tipc: remove include file port.h Jon Maloy
@ 2014-08-22 22:09 ` Jon Maloy
  2014-08-22 22:09 ` [PATCH net-next 17/17] tipc: merge struct tipc_port into struct tipc_sock Jon Maloy
  2014-08-23 18:19 ` [PATCH net-next 00/17] tipc: Merge port and socket layer code David Miller
  17 siblings, 0 replies; 22+ messages in thread
From: Jon Maloy @ 2014-08-22 22:09 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, Paul Gortmaker, tipc-discussion

The reference table is now 'socket aware' instead of being generic,
and has in reality become a socket internal table. In order to be
able to minimize the API exposed by the socket layer towards the rest
of the stack, we now move the reference table definitions and functions
into the file socket.c, and rename the functions accordingly.

There are no functional changes in this commit.

Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Ying Xue <ying.xue@windriver.com>
---
 net/tipc/Makefile |    2 +-
 net/tipc/core.c   |    7 +-
 net/tipc/ref.c    |  270 -----------------------------------------------------
 net/tipc/ref.h    |   56 -----------
 net/tipc/socket.c |  247 +++++++++++++++++++++++++++++++++++++++++++++++-
 net/tipc/socket.h |    2 +
 6 files changed, 250 insertions(+), 334 deletions(-)
 delete mode 100644 net/tipc/ref.c
 delete mode 100644 net/tipc/ref.h

diff --git a/net/tipc/Makefile b/net/tipc/Makefile
index 5206a44..b8a13ca 100644
--- a/net/tipc/Makefile
+++ b/net/tipc/Makefile
@@ -7,7 +7,7 @@ obj-$(CONFIG_TIPC) := tipc.o
 tipc-y	+= addr.o bcast.o bearer.o config.o \
 	   core.o link.o discover.o msg.o  \
 	   name_distr.o  subscr.o name_table.o net.o  \
-	   netlink.o node.o node_subscr.o ref.o  \
+	   netlink.o node.o node_subscr.o \
 	   socket.o log.o eth_media.o server.o
 
 tipc-$(CONFIG_TIPC_MEDIA_IB)	+= ib_media.o
diff --git a/net/tipc/core.c b/net/tipc/core.c
index b3b03ef..a5737b8 100644
--- a/net/tipc/core.c
+++ b/net/tipc/core.c
@@ -35,7 +35,6 @@
  */
 
 #include "core.h"
-#include "ref.h"
 #include "name_table.h"
 #include "subscr.h"
 #include "config.h"
@@ -85,7 +84,7 @@ static void tipc_core_stop(void)
 	tipc_netlink_stop();
 	tipc_subscr_stop();
 	tipc_nametbl_stop();
-	tipc_ref_table_stop();
+	tipc_sk_ref_table_stop();
 	tipc_socket_stop();
 	tipc_unregister_sysctl();
 }
@@ -99,7 +98,7 @@ static int tipc_core_start(void)
 
 	get_random_bytes(&tipc_random, sizeof(tipc_random));
 
-	err = tipc_ref_table_init(tipc_max_ports, tipc_random);
+	err = tipc_sk_ref_table_init(tipc_max_ports, tipc_random);
 	if (err)
 		goto out_reftbl;
 
@@ -139,7 +138,7 @@ out_socket:
 out_netlink:
 	tipc_nametbl_stop();
 out_nametbl:
-	tipc_ref_table_stop();
+	tipc_sk_ref_table_stop();
 out_reftbl:
 	return err;
 }
diff --git a/net/tipc/ref.c b/net/tipc/ref.c
deleted file mode 100644
index ea981be..0000000
--- a/net/tipc/ref.c
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * net/tipc/ref.c: TIPC socket registry code
- *
- * Copyright (c) 1991-2006, 2014, Ericsson AB
- * Copyright (c) 2004-2007, Wind River Systems
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the names of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "core.h"
-#include "ref.h"
-
-/**
- * struct reference - TIPC socket reference entry
- * @tsk: pointer to socket associated with reference entry
- * @ref: reference value for socket (combines instance & array index info)
- */
-struct reference {
-	struct tipc_sock *tsk;
-	u32 ref;
-};
-
-/**
- * struct tipc_ref_table - table of TIPC socket reference entries
- * @entries: pointer to array of reference entries
- * @capacity: array index of first unusable entry
- * @init_point: array index of first uninitialized entry
- * @first_free: array index of first unused socket reference entry
- * @last_free: array index of last unused socket reference entry
- * @index_mask: bitmask for array index portion of reference values
- * @start_mask: initial value for instance value portion of reference values
- */
-struct ref_table {
-	struct reference *entries;
-	u32 capacity;
-	u32 init_point;
-	u32 first_free;
-	u32 last_free;
-	u32 index_mask;
-	u32 start_mask;
-};
-
-/*
- * Socket reference table consists of 2**N entries.
- *
- * State	Socket ptr	Reference
- * -----        ----------      ---------
- * In use        non-NULL       XXXX|own index
- *				(XXXX changes each time entry is acquired)
- * Free            NULL         YYYY|next free index
- *				(YYYY is one more than last used XXXX)
- * Uninitialized   NULL         0
- *
- * Entry 0 is not used; this allows index 0 to denote the end of the free list.
- *
- * Note that a reference value of 0 does not necessarily indicate that an
- * entry is uninitialized, since the last entry in the free list could also
- * have a reference value of 0 (although this is unlikely).
- */
-
-static struct ref_table tipc_ref_table;
-
-static DEFINE_RWLOCK(ref_table_lock);
-
-/**
- * tipc_ref_table_init - create reference table for sockets
- */
-int tipc_ref_table_init(u32 requested_size, u32 start)
-{
-	struct reference *table;
-	u32 actual_size;
-
-	/* account for unused entry, then round up size to a power of 2 */
-
-	requested_size++;
-	for (actual_size = 16; actual_size < requested_size; actual_size <<= 1)
-		/* do nothing */ ;
-
-	/* allocate table & mark all entries as uninitialized */
-	table = vzalloc(actual_size * sizeof(struct reference));
-	if (table == NULL)
-		return -ENOMEM;
-
-	tipc_ref_table.entries = table;
-	tipc_ref_table.capacity = requested_size;
-	tipc_ref_table.init_point = 1;
-	tipc_ref_table.first_free = 0;
-	tipc_ref_table.last_free = 0;
-	tipc_ref_table.index_mask = actual_size - 1;
-	tipc_ref_table.start_mask = start & ~tipc_ref_table.index_mask;
-
-	return 0;
-}
-
-/**
- * tipc_ref_table_stop - destroy reference table for sockets
- */
-void tipc_ref_table_stop(void)
-{
-	if (!tipc_ref_table.entries)
-		return;
-	vfree(tipc_ref_table.entries);
-	tipc_ref_table.entries = NULL;
-}
-
-/* tipc_ref_acquire - create reference to a socket
- *
- * Register an socket pointer in the reference table.
- * Returns a unique reference value that is used from then on to retrieve the
- * socket pointer, or to determine if the socket has been deregistered.
- */
-u32 tipc_ref_acquire(struct tipc_sock *tsk)
-{
-	u32 index;
-	u32 index_mask;
-	u32 next_plus_upper;
-	u32 ref = 0;
-	struct reference *entry;
-
-	if (unlikely(!tsk)) {
-		pr_err("Attempt to acquire ref. to non-existent obj\n");
-		return 0;
-	}
-	if (unlikely(!tipc_ref_table.entries)) {
-		pr_err("Ref. table not found in acquisition attempt\n");
-		return 0;
-	}
-
-	/* Take a free entry, if available; otherwise initialize a new one */
-	write_lock_bh(&ref_table_lock);
-	index = tipc_ref_table.first_free;
-	entry = &tipc_ref_table.entries[index];
-
-	if (likely(index)) {
-		index = tipc_ref_table.first_free;
-		entry = &(tipc_ref_table.entries[index]);
-		index_mask = tipc_ref_table.index_mask;
-		next_plus_upper = entry->ref;
-		tipc_ref_table.first_free = next_plus_upper & index_mask;
-		ref = (next_plus_upper & ~index_mask) + index;
-		entry->tsk = tsk;
-	} else if (tipc_ref_table.init_point < tipc_ref_table.capacity) {
-		index = tipc_ref_table.init_point++;
-		entry = &(tipc_ref_table.entries[index]);
-		ref = tipc_ref_table.start_mask + index;
-	}
-
-	if (ref) {
-		entry->ref = ref;
-		entry->tsk = tsk;
-	}
-	write_unlock_bh(&ref_table_lock);
-	return ref;
-}
-
-/* tipc_ref_discard - invalidate reference to an socket
- *
- * Disallow future references to an socket and free up the entry for re-use.
- */
-void tipc_ref_discard(u32 ref)
-{
-	struct reference *entry;
-	u32 index;
-	u32 index_mask;
-
-	if (unlikely(!tipc_ref_table.entries)) {
-		pr_err("Ref. table not found during discard attempt\n");
-		return;
-	}
-
-	index_mask = tipc_ref_table.index_mask;
-	index = ref & index_mask;
-	entry = &(tipc_ref_table.entries[index]);
-
-	write_lock_bh(&ref_table_lock);
-
-	if (unlikely(!entry->tsk)) {
-		pr_err("Attempt to discard ref. to non-existent socket\n");
-		goto exit;
-	}
-	if (unlikely(entry->ref != ref)) {
-		pr_err("Attempt to discard non-existent reference\n");
-		goto exit;
-	}
-
-	/*
-	 * Mark entry as unused; increment instance part of entry's reference
-	 * to invalidate any subsequent references
-	 */
-	entry->tsk = NULL;
-	entry->ref = (ref & ~index_mask) + (index_mask + 1);
-
-	/* Append entry to free entry list */
-	if (unlikely(tipc_ref_table.first_free == 0))
-		tipc_ref_table.first_free = index;
-	else
-		tipc_ref_table.entries[tipc_ref_table.last_free].ref |= index;
-	tipc_ref_table.last_free = index;
-exit:
-	write_unlock_bh(&ref_table_lock);
-}
-
-/* tipc_sk_get - find referenced socket and return pointer to it
- */
-struct tipc_sock *tipc_sk_get(u32 ref)
-{
-	struct reference *entry;
-	struct tipc_sock *tsk;
-
-	if (unlikely(!tipc_ref_table.entries))
-		return NULL;
-	read_lock_bh(&ref_table_lock);
-	entry = &tipc_ref_table.entries[ref & tipc_ref_table.index_mask];
-	tsk = entry->tsk;
-	if (likely(tsk && (entry->ref == ref)))
-		sock_hold(&tsk->sk);
-	else
-		tsk = NULL;
-	read_unlock_bh(&ref_table_lock);
-	return tsk;
-}
-
-/* tipc_sk_get_next - lock & return next socket after referenced one
-*/
-struct tipc_sock *tipc_sk_get_next(u32 *ref)
-{
-	struct reference *entry;
-	struct tipc_sock *tsk = NULL;
-	uint index = *ref & tipc_ref_table.index_mask;
-
-	read_lock_bh(&ref_table_lock);
-	while (++index < tipc_ref_table.capacity) {
-		entry = &tipc_ref_table.entries[index];
-		if (!entry->tsk)
-			continue;
-		tsk = entry->tsk;
-		sock_hold(&tsk->sk);
-		*ref = entry->ref;
-		break;
-	}
-	read_unlock_bh(&ref_table_lock);
-	return tsk;
-}
diff --git a/net/tipc/ref.h b/net/tipc/ref.h
deleted file mode 100644
index 2b75a89..0000000
--- a/net/tipc/ref.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * net/tipc/ref.h: Include file for TIPC object registry code
- *
- * Copyright (c) 1991-2006, 2014, Ericsson AB
- * Copyright (c) 2005-2006, Wind River Systems
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the names of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _TIPC_REF_H
-#define _TIPC_REF_H
-
-#include "socket.h"
-
-int tipc_ref_table_init(u32 requested_size, u32 start);
-void tipc_ref_table_stop(void);
-
-u32 tipc_ref_acquire(struct tipc_sock *tsk);
-void tipc_ref_discard(u32 ref);
-
-struct tipc_sock *tipc_sk_get(u32 ref);
-struct tipc_sock *tipc_sk_get_next(u32 *ref);
-
-static inline void tipc_sk_put(struct tipc_sock *tsk)
-{
-	sock_put(&tsk->sk);
-}
-
-#endif
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 70eacea..6a69967 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -35,7 +35,6 @@
  */
 
 #include "core.h"
-#include "ref.h"
 #include "name_table.h"
 #include "node.h"
 #include "link.h"
@@ -61,6 +60,11 @@ static int tipc_sk_publish(struct tipc_port *port, uint scope,
 			   struct tipc_name_seq const *seq);
 static int tipc_sk_withdraw(struct tipc_port *port, uint scope,
 			    struct tipc_name_seq const *seq);
+static u32 tipc_sk_ref_acquire(struct tipc_sock *tsk);
+static void tipc_sk_ref_discard(u32 ref);
+static struct tipc_sock *tipc_sk_get(u32 ref);
+static struct tipc_sock *tipc_sk_get_next(u32 *ref);
+static void tipc_sk_put(struct tipc_sock *tsk);
 
 static const struct proto_ops packet_ops;
 static const struct proto_ops stream_ops;
@@ -271,7 +275,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
 
 	tsk = tipc_sk(sk);
 	port = &tsk->port;
-	ref = tipc_ref_acquire(tsk);
+	ref = tipc_sk_ref_acquire(tsk);
 	if (!ref) {
 		pr_warn("Socket create failed; reference table exhausted\n");
 		return -ENOMEM;
@@ -434,7 +438,7 @@ static int tipc_release(struct socket *sock)
 	}
 
 	tipc_sk_withdraw(port, 0, NULL);
-	tipc_ref_discard(port->ref);
+	tipc_sk_ref_discard(port->ref);
 	k_cancel_timer(&port->timer);
 	if (port->connected) {
 		buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG,
@@ -2254,6 +2258,243 @@ void tipc_sk_reinit(void)
 }
 
 /**
+ * struct reference - TIPC socket reference entry
+ * @tsk: pointer to socket associated with reference entry
+ * @ref: reference value for socket (combines instance & array index info)
+ */
+struct reference {
+	struct tipc_sock *tsk;
+	u32 ref;
+};
+
+/**
+ * struct tipc_ref_table - table of TIPC socket reference entries
+ * @entries: pointer to array of reference entries
+ * @capacity: array index of first unusable entry
+ * @init_point: array index of first uninitialized entry
+ * @first_free: array index of first unused socket reference entry
+ * @last_free: array index of last unused socket reference entry
+ * @index_mask: bitmask for array index portion of reference values
+ * @start_mask: initial value for instance value portion of reference values
+ */
+struct ref_table {
+	struct reference *entries;
+	u32 capacity;
+	u32 init_point;
+	u32 first_free;
+	u32 last_free;
+	u32 index_mask;
+	u32 start_mask;
+};
+
+/* Socket reference table consists of 2**N entries.
+ *
+ * State	Socket ptr	Reference
+ * -----        ----------      ---------
+ * In use        non-NULL       XXXX|own index
+ *				(XXXX changes each time entry is acquired)
+ * Free            NULL         YYYY|next free index
+ *				(YYYY is one more than last used XXXX)
+ * Uninitialized   NULL         0
+ *
+ * Entry 0 is not used; this allows index 0 to denote the end of the free list.
+ *
+ * Note that a reference value of 0 does not necessarily indicate that an
+ * entry is uninitialized, since the last entry in the free list could also
+ * have a reference value of 0 (although this is unlikely).
+ */
+
+static struct ref_table tipc_ref_table;
+
+static DEFINE_RWLOCK(ref_table_lock);
+
+/**
+ * tipc_ref_table_init - create reference table for sockets
+ */
+int tipc_sk_ref_table_init(u32 req_sz, u32 start)
+{
+	struct reference *table;
+	u32 actual_sz;
+
+	/* account for unused entry, then round up size to a power of 2 */
+
+	req_sz++;
+	for (actual_sz = 16; actual_sz < req_sz; actual_sz <<= 1) {
+		/* do nothing */
+	};
+
+	/* allocate table & mark all entries as uninitialized */
+	table = vzalloc(actual_sz * sizeof(struct reference));
+	if (table == NULL)
+		return -ENOMEM;
+
+	tipc_ref_table.entries = table;
+	tipc_ref_table.capacity = req_sz;
+	tipc_ref_table.init_point = 1;
+	tipc_ref_table.first_free = 0;
+	tipc_ref_table.last_free = 0;
+	tipc_ref_table.index_mask = actual_sz - 1;
+	tipc_ref_table.start_mask = start & ~tipc_ref_table.index_mask;
+
+	return 0;
+}
+
+/**
+ * tipc_ref_table_stop - destroy reference table for sockets
+ */
+void tipc_sk_ref_table_stop(void)
+{
+	if (!tipc_ref_table.entries)
+		return;
+	vfree(tipc_ref_table.entries);
+	tipc_ref_table.entries = NULL;
+}
+
+/* tipc_ref_acquire - create reference to a socket
+ *
+ * Register an socket pointer in the reference table.
+ * Returns a unique reference value that is used from then on to retrieve the
+ * socket pointer, or to determine if the socket has been deregistered.
+ */
+u32 tipc_sk_ref_acquire(struct tipc_sock *tsk)
+{
+	u32 index;
+	u32 index_mask;
+	u32 next_plus_upper;
+	u32 ref = 0;
+	struct reference *entry;
+
+	if (unlikely(!tsk)) {
+		pr_err("Attempt to acquire ref. to non-existent obj\n");
+		return 0;
+	}
+	if (unlikely(!tipc_ref_table.entries)) {
+		pr_err("Ref. table not found in acquisition attempt\n");
+		return 0;
+	}
+
+	/* Take a free entry, if available; otherwise initialize a new one */
+	write_lock_bh(&ref_table_lock);
+	index = tipc_ref_table.first_free;
+	entry = &tipc_ref_table.entries[index];
+
+	if (likely(index)) {
+		index = tipc_ref_table.first_free;
+		entry = &tipc_ref_table.entries[index];
+		index_mask = tipc_ref_table.index_mask;
+		next_plus_upper = entry->ref;
+		tipc_ref_table.first_free = next_plus_upper & index_mask;
+		ref = (next_plus_upper & ~index_mask) + index;
+		entry->tsk = tsk;
+	} else if (tipc_ref_table.init_point < tipc_ref_table.capacity) {
+		index = tipc_ref_table.init_point++;
+		entry = &tipc_ref_table.entries[index];
+		ref = tipc_ref_table.start_mask + index;
+	}
+
+	if (ref) {
+		entry->ref = ref;
+		entry->tsk = tsk;
+	}
+	write_unlock_bh(&ref_table_lock);
+	return ref;
+}
+
+/* tipc_sk_ref_discard - invalidate reference to an socket
+ *
+ * Disallow future references to an socket and free up the entry for re-use.
+ */
+void tipc_sk_ref_discard(u32 ref)
+{
+	struct reference *entry;
+	u32 index;
+	u32 index_mask;
+
+	if (unlikely(!tipc_ref_table.entries)) {
+		pr_err("Ref. table not found during discard attempt\n");
+		return;
+	}
+
+	index_mask = tipc_ref_table.index_mask;
+	index = ref & index_mask;
+	entry = &tipc_ref_table.entries[index];
+
+	write_lock_bh(&ref_table_lock);
+
+	if (unlikely(!entry->tsk)) {
+		pr_err("Attempt to discard ref. to non-existent socket\n");
+		goto exit;
+	}
+	if (unlikely(entry->ref != ref)) {
+		pr_err("Attempt to discard non-existent reference\n");
+		goto exit;
+	}
+
+	/* Mark entry as unused; increment instance part of entry's
+	 *   reference to invalidate any subsequent references
+	 */
+
+	entry->tsk = NULL;
+	entry->ref = (ref & ~index_mask) + (index_mask + 1);
+
+	/* Append entry to free entry list */
+	if (unlikely(tipc_ref_table.first_free == 0))
+		tipc_ref_table.first_free = index;
+	else
+		tipc_ref_table.entries[tipc_ref_table.last_free].ref |= index;
+	tipc_ref_table.last_free = index;
+exit:
+	write_unlock_bh(&ref_table_lock);
+}
+
+/* tipc_sk_get - find referenced socket and return pointer to it
+ */
+struct tipc_sock *tipc_sk_get(u32 ref)
+{
+	struct reference *entry;
+	struct tipc_sock *tsk;
+
+	if (unlikely(!tipc_ref_table.entries))
+		return NULL;
+	read_lock_bh(&ref_table_lock);
+	entry = &tipc_ref_table.entries[ref & tipc_ref_table.index_mask];
+	tsk = entry->tsk;
+	if (likely(tsk && (entry->ref == ref)))
+		sock_hold(&tsk->sk);
+	else
+		tsk = NULL;
+	read_unlock_bh(&ref_table_lock);
+	return tsk;
+}
+
+/* tipc_sk_get_next - lock & return next socket after referenced one
+*/
+struct tipc_sock *tipc_sk_get_next(u32 *ref)
+{
+	struct reference *entry;
+	struct tipc_sock *tsk = NULL;
+	uint index = *ref & tipc_ref_table.index_mask;
+
+	read_lock_bh(&ref_table_lock);
+	while (++index < tipc_ref_table.capacity) {
+		entry = &tipc_ref_table.entries[index];
+		if (!entry->tsk)
+			continue;
+		tsk = entry->tsk;
+		sock_hold(&tsk->sk);
+		*ref = entry->ref;
+		break;
+	}
+	read_unlock_bh(&ref_table_lock);
+	return tsk;
+}
+
+static void tipc_sk_put(struct tipc_sock *tsk)
+{
+	sock_put(&tsk->sk);
+}
+
+/**
  * tipc_setsockopt - set socket option
  * @sock: socket structure
  * @lvl: option level
diff --git a/net/tipc/socket.h b/net/tipc/socket.h
index b98725e..4877216 100644
--- a/net/tipc/socket.h
+++ b/net/tipc/socket.h
@@ -119,5 +119,7 @@ int tipc_sk_rcv(struct sk_buff *buf);
 struct sk_buff *tipc_sk_socks_show(void);
 void tipc_sk_mcast_rcv(struct sk_buff *buf);
 void tipc_sk_reinit(void);
+int tipc_sk_ref_table_init(u32 requested_size, u32 start);
+void tipc_sk_ref_table_stop(void);
 
 #endif
-- 
1.7.9.5


------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH net-next 17/17] tipc: merge struct tipc_port into struct tipc_sock
  2014-08-22 22:09 [PATCH net-next 00/17] tipc: Merge port and socket layer code Jon Maloy
                   ` (15 preceding siblings ...)
  2014-08-22 22:09 ` [PATCH net-next 16/17] tipc: remove files ref.h and ref.c Jon Maloy
@ 2014-08-22 22:09 ` Jon Maloy
  2014-08-23 18:19 ` [PATCH net-next 00/17] tipc: Merge port and socket layer code David Miller
  17 siblings, 0 replies; 22+ messages in thread
From: Jon Maloy @ 2014-08-22 22:09 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, Paul Gortmaker, tipc-discussion

We complete the merging of the port and socket layer by aggregating
the fields of struct tipc_port directly into struct tipc_sock, and
moving the combined structure into socket.c.

We also move all functions and macros that are not any longer
exposed to the rest of the stack into socket.c, and rename them
accordingly.

Despite the size of this commit, there are no functional changes.
We have only made such changes that are necessary due of the removal
of struct tipc_port.

Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Ying Xue <ying.xue@windriver.com>
---
 net/tipc/socket.c |  373 +++++++++++++++++++++++++++++------------------------
 net/tipc/socket.h |   74 -----------
 2 files changed, 206 insertions(+), 241 deletions(-)

diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 6a69967..d416e83 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -45,9 +45,57 @@
 #define SS_LISTENING	-1	/* socket is listening */
 #define SS_READY	-2	/* socket is connectionless */
 
-#define CONN_TIMEOUT_DEFAULT	8000	/* default connect timeout = 8s */
+#define CONN_TIMEOUT_DEFAULT  8000	/* default connect timeout = 8s */
 #define CONN_PROBING_INTERVAL 3600000	/* [ms] => 1 h */
-#define TIPC_FWD_MSG	        1
+#define TIPC_FWD_MSG	      1
+#define TIPC_CONN_OK          0
+#define TIPC_CONN_PROBING     1
+
+/**
+ * struct tipc_sock - TIPC socket structure
+ * @sk: socket - interacts with 'port' and with user via the socket API
+ * @connected: non-zero if port is currently connected to a peer port
+ * @conn_type: TIPC type used when connection was established
+ * @conn_instance: TIPC instance used when connection was established
+ * @published: non-zero if port has one or more associated names
+ * @max_pkt: maximum packet size "hint" used when building messages sent by port
+ * @ref: unique reference to port in TIPC object registry
+ * @phdr: preformatted message header used when sending messages
+ * @port_list: adjacent ports in TIPC's global list of ports
+ * @publications: list of publications for port
+ * @pub_count: total # of publications port has made during its lifetime
+ * @probing_state:
+ * @probing_interval:
+ * @timer:
+ * @port: port - interacts with 'sk' and with the rest of the TIPC stack
+ * @peer_name: the peer of the connection, if any
+ * @conn_timeout: the time we can wait for an unresponded setup request
+ * @dupl_rcvcnt: number of bytes counted twice, in both backlog and rcv queue
+ * @link_cong: non-zero if owner must sleep because of link congestion
+ * @sent_unacked: # messages sent by socket, and not yet acked by peer
+ * @rcv_unacked: # messages read by user, but not yet acked back to peer
+ */
+struct tipc_sock {
+	struct sock sk;
+	int connected;
+	u32 conn_type;
+	u32 conn_instance;
+	int published;
+	u32 max_pkt;
+	u32 ref;
+	struct tipc_msg phdr;
+	struct list_head sock_list;
+	struct list_head publications;
+	u32 pub_count;
+	u32 probing_state;
+	u32 probing_interval;
+	struct timer_list timer;
+	uint conn_timeout;
+	atomic_t dupl_rcvcnt;
+	bool link_cong;
+	uint sent_unacked;
+	uint rcv_unacked;
+};
 
 static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb);
 static void tipc_data_ready(struct sock *sk);
@@ -56,9 +104,9 @@ static int tipc_release(struct socket *sock);
 static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags);
 static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p);
 static void tipc_sk_timeout(unsigned long ref);
-static int tipc_sk_publish(struct tipc_port *port, uint scope,
+static int tipc_sk_publish(struct tipc_sock *tsk, uint scope,
 			   struct tipc_name_seq const *seq);
-static int tipc_sk_withdraw(struct tipc_port *port, uint scope,
+static int tipc_sk_withdraw(struct tipc_sock *tsk, uint scope,
 			    struct tipc_name_seq const *seq);
 static u32 tipc_sk_ref_acquire(struct tipc_sock *tsk);
 static void tipc_sk_ref_discard(u32 ref);
@@ -118,49 +166,59 @@ static struct proto tipc_proto_kern;
  *   - port reference
  */
 
-static u32 tsk_peer_node(struct tipc_port *p_ptr)
+static u32 tsk_peer_node(struct tipc_sock *tsk)
 {
-	return msg_destnode(&p_ptr->phdr);
+	return msg_destnode(&tsk->phdr);
 }
 
-static u32 tsk_peer_port(struct tipc_port *p_ptr)
+static u32 tsk_peer_port(struct tipc_sock *tsk)
 {
-	return msg_destport(&p_ptr->phdr);
+	return msg_destport(&tsk->phdr);
 }
 
-static  bool tsk_unreliable(struct tipc_port *port)
+static  bool tsk_unreliable(struct tipc_sock *tsk)
 {
-	return msg_src_droppable(&port->phdr) != 0;
+	return msg_src_droppable(&tsk->phdr) != 0;
 }
 
-static void tsk_set_unreliable(struct tipc_port *port, bool unreliable)
+static void tsk_set_unreliable(struct tipc_sock *tsk, bool unreliable)
 {
-	msg_set_src_droppable(&port->phdr, unreliable ? 1 : 0);
+	msg_set_src_droppable(&tsk->phdr, unreliable ? 1 : 0);
 }
 
-static bool tsk_unreturnable(struct tipc_port *port)
+static bool tsk_unreturnable(struct tipc_sock *tsk)
 {
-	return msg_dest_droppable(&port->phdr) != 0;
+	return msg_dest_droppable(&tsk->phdr) != 0;
 }
 
-static void tsk_set_unreturnable(struct tipc_port *port, bool unreturnable)
+static void tsk_set_unreturnable(struct tipc_sock *tsk, bool unreturnable)
 {
-	msg_set_dest_droppable(&port->phdr, unreturnable ? 1 : 0);
+	msg_set_dest_droppable(&tsk->phdr, unreturnable ? 1 : 0);
 }
 
-static int tsk_importance(struct tipc_port *port)
+static int tsk_importance(struct tipc_sock *tsk)
 {
-	return msg_importance(&port->phdr);
+	return msg_importance(&tsk->phdr);
 }
 
-static int tsk_set_importance(struct tipc_port *port, int imp)
+static int tsk_set_importance(struct tipc_sock *tsk, int imp)
 {
 	if (imp > TIPC_CRITICAL_IMPORTANCE)
 		return -EINVAL;
-	msg_set_importance(&port->phdr, (u32)imp);
+	msg_set_importance(&tsk->phdr, (u32)imp);
 	return 0;
 }
 
+static struct tipc_sock *tipc_sk(const struct sock *sk)
+{
+	return container_of(sk, struct tipc_sock, sk);
+}
+
+static int tsk_conn_cong(struct tipc_sock *tsk)
+{
+	return tsk->sent_unacked >= TIPC_FLOWCTRL_WIN;
+}
+
 /**
  * tsk_advance_rx_queue - discard first buffer in socket receive queue
  *
@@ -194,18 +252,18 @@ static void tsk_rej_rx_queue(struct sock *sk)
  */
 static bool tsk_peer_msg(struct tipc_sock *tsk, struct tipc_msg *msg)
 {
-	u32 peer_port = tsk_peer_port(&tsk->port);
+	u32 peer_port = tsk_peer_port(tsk);
 	u32 orig_node;
 	u32 peer_node;
 
-	if (unlikely(!tsk->port.connected))
+	if (unlikely(!tsk->connected))
 		return false;
 
 	if (unlikely(msg_origport(msg) != peer_port))
 		return false;
 
 	orig_node = msg_orignode(msg);
-	peer_node = tsk_peer_node(&tsk->port);
+	peer_node = tsk_peer_node(tsk);
 
 	if (likely(orig_node == peer_node))
 		return true;
@@ -238,7 +296,6 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
 	socket_state state;
 	struct sock *sk;
 	struct tipc_sock *tsk;
-	struct tipc_port *port;
 	struct tipc_msg *msg;
 	u32 ref;
 
@@ -274,17 +331,15 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
 		return -ENOMEM;
 
 	tsk = tipc_sk(sk);
-	port = &tsk->port;
 	ref = tipc_sk_ref_acquire(tsk);
 	if (!ref) {
 		pr_warn("Socket create failed; reference table exhausted\n");
 		return -ENOMEM;
 	}
-	port->max_pkt = MAX_PKT_DEFAULT;
-	port->ref = ref;
-	INIT_LIST_HEAD(&port->publications);
-
-	msg = &port->phdr;
+	tsk->max_pkt = MAX_PKT_DEFAULT;
+	tsk->ref = ref;
+	INIT_LIST_HEAD(&tsk->publications);
+	msg = &tsk->phdr;
 	tipc_msg_init(msg, TIPC_LOW_IMPORTANCE, TIPC_NAMED_MSG,
 		      NAMED_H_SIZE, 0);
 	msg_set_origport(msg, ref);
@@ -293,7 +348,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
 	sock->ops = ops;
 	sock->state = state;
 	sock_init_data(sock, sk);
-	k_init_timer(&port->timer, (Handler)tipc_sk_timeout, ref);
+	k_init_timer(&tsk->timer, (Handler)tipc_sk_timeout, ref);
 	sk->sk_backlog_rcv = tipc_backlog_rcv;
 	sk->sk_rcvbuf = sysctl_tipc_rmem[1];
 	sk->sk_data_ready = tipc_data_ready;
@@ -303,9 +358,9 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
 	atomic_set(&tsk->dupl_rcvcnt, 0);
 
 	if (sock->state == SS_READY) {
-		tsk_set_unreturnable(port, true);
+		tsk_set_unreturnable(tsk, true);
 		if (sock->type == SOCK_DGRAM)
-			tsk_set_unreliable(port, true);
+			tsk_set_unreliable(tsk, true);
 	}
 	return 0;
 }
@@ -399,7 +454,6 @@ static int tipc_release(struct socket *sock)
 {
 	struct sock *sk = sock->sk;
 	struct tipc_sock *tsk;
-	struct tipc_port *port;
 	struct sk_buff *buf;
 	u32 dnode;
 
@@ -411,14 +465,13 @@ static int tipc_release(struct socket *sock)
 		return 0;
 
 	tsk = tipc_sk(sk);
-	port = &tsk->port;
 	lock_sock(sk);
 
 	/*
 	 * Reject all unreceived messages, except on an active connection
 	 * (which disconnects locally & sends a 'FIN+' to peer)
 	 */
-	dnode = tsk_peer_node(port);
+	dnode = tsk_peer_node(tsk);
 	while (sock->state != SS_DISCONNECTING) {
 		buf = __skb_dequeue(&sk->sk_receive_queue);
 		if (buf == NULL)
@@ -429,27 +482,27 @@ static int tipc_release(struct socket *sock)
 			if ((sock->state == SS_CONNECTING) ||
 			    (sock->state == SS_CONNECTED)) {
 				sock->state = SS_DISCONNECTING;
-				port->connected = 0;
-				tipc_node_remove_conn(dnode, port->ref);
+				tsk->connected = 0;
+				tipc_node_remove_conn(dnode, tsk->ref);
 			}
 			if (tipc_msg_reverse(buf, &dnode, TIPC_ERR_NO_PORT))
 				tipc_link_xmit(buf, dnode, 0);
 		}
 	}
 
-	tipc_sk_withdraw(port, 0, NULL);
-	tipc_sk_ref_discard(port->ref);
-	k_cancel_timer(&port->timer);
-	if (port->connected) {
+	tipc_sk_withdraw(tsk, 0, NULL);
+	tipc_sk_ref_discard(tsk->ref);
+	k_cancel_timer(&tsk->timer);
+	if (tsk->connected) {
 		buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG,
 				      SHORT_H_SIZE, 0, dnode, tipc_own_addr,
-				      tsk_peer_port(port),
-				      port->ref, TIPC_ERR_NO_PORT);
+				      tsk_peer_port(tsk),
+				      tsk->ref, TIPC_ERR_NO_PORT);
 		if (buf)
-			tipc_link_xmit(buf, dnode, port->ref);
-		tipc_node_remove_conn(dnode, port->ref);
+			tipc_link_xmit(buf, dnode, tsk->ref);
+		tipc_node_remove_conn(dnode, tsk->ref);
 	}
-	k_term_timer(&port->timer);
+	k_term_timer(&tsk->timer);
 
 	/* Discard any remaining (connection-based) messages in receive queue */
 	__skb_queue_purge(&sk->sk_receive_queue);
@@ -488,7 +541,7 @@ static int tipc_bind(struct socket *sock, struct sockaddr *uaddr,
 
 	lock_sock(sk);
 	if (unlikely(!uaddr_len)) {
-		res = tipc_sk_withdraw(&tsk->port, 0, NULL);
+		res = tipc_sk_withdraw(tsk, 0, NULL);
 		goto exit;
 	}
 
@@ -516,8 +569,8 @@ static int tipc_bind(struct socket *sock, struct sockaddr *uaddr,
 	}
 
 	res = (addr->scope > 0) ?
-		tipc_sk_publish(&tsk->port, addr->scope, &addr->addr.nameseq) :
-		tipc_sk_withdraw(&tsk->port, -addr->scope, &addr->addr.nameseq);
+		tipc_sk_publish(tsk, addr->scope, &addr->addr.nameseq) :
+		tipc_sk_withdraw(tsk, -addr->scope, &addr->addr.nameseq);
 exit:
 	release_sock(sk);
 	return res;
@@ -547,10 +600,10 @@ static int tipc_getname(struct socket *sock, struct sockaddr *uaddr,
 		if ((sock->state != SS_CONNECTED) &&
 			((peer != 2) || (sock->state != SS_DISCONNECTING)))
 			return -ENOTCONN;
-		addr->addr.id.ref = tsk_peer_port(&tsk->port);
-		addr->addr.id.node = tsk_peer_node(&tsk->port);
+		addr->addr.id.ref = tsk_peer_port(tsk);
+		addr->addr.id.node = tsk_peer_node(tsk);
 	} else {
-		addr->addr.id.ref = tsk->port.ref;
+		addr->addr.id.ref = tsk->ref;
 		addr->addr.id.node = tipc_own_addr;
 	}
 
@@ -619,7 +672,7 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
 		break;
 	case SS_READY:
 	case SS_CONNECTED:
-		if (!tsk->link_cong && !tipc_sk_conn_cong(tsk))
+		if (!tsk->link_cong && !tsk_conn_cong(tsk))
 			mask |= POLLOUT;
 		/* fall thru' */
 	case SS_CONNECTING:
@@ -650,7 +703,7 @@ static int tipc_sendmcast(struct  socket *sock, struct tipc_name_seq *seq,
 			  struct iovec *iov, size_t dsz, long timeo)
 {
 	struct sock *sk = sock->sk;
-	struct tipc_msg *mhdr = &tipc_sk(sk)->port.phdr;
+	struct tipc_msg *mhdr = &tipc_sk(sk)->phdr;
 	struct sk_buff *buf;
 	uint mtu;
 	int rc;
@@ -740,17 +793,16 @@ static int tipc_sk_proto_rcv(struct tipc_sock *tsk, u32 *dnode,
 			     struct sk_buff *buf)
 {
 	struct tipc_msg *msg = buf_msg(buf);
-	struct tipc_port *port = &tsk->port;
 	int conn_cong;
 
 	/* Ignore if connection cannot be validated: */
 	if (!tsk_peer_msg(tsk, msg))
 		goto exit;
 
-	port->probing_state = TIPC_CONN_OK;
+	tsk->probing_state = TIPC_CONN_OK;
 
 	if (msg_type(msg) == CONN_ACK) {
-		conn_cong = tipc_sk_conn_cong(tsk);
+		conn_cong = tsk_conn_cong(tsk);
 		tsk->sent_unacked -= msg_msgcnt(msg);
 		if (conn_cong)
 			tsk->sk.sk_write_space(&tsk->sk);
@@ -844,8 +896,7 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock,
 	DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name);
 	struct sock *sk = sock->sk;
 	struct tipc_sock *tsk = tipc_sk(sk);
-	struct tipc_port *port = &tsk->port;
-	struct tipc_msg *mhdr = &port->phdr;
+	struct tipc_msg *mhdr = &tsk->phdr;
 	struct iovec *iov = m->msg_iov;
 	u32 dnode, dport;
 	struct sk_buff *buf;
@@ -876,13 +927,13 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock,
 			rc = -EISCONN;
 			goto exit;
 		}
-		if (tsk->port.published) {
+		if (tsk->published) {
 			rc = -EOPNOTSUPP;
 			goto exit;
 		}
 		if (dest->addrtype == TIPC_ADDR_NAME) {
-			tsk->port.conn_type = dest->addr.name.name.type;
-			tsk->port.conn_instance = dest->addr.name.name.instance;
+			tsk->conn_type = dest->addr.name.name.type;
+			tsk->conn_instance = dest->addr.name.name.instance;
 		}
 	}
 	rc = dest_name_check(dest, m);
@@ -922,14 +973,14 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock,
 	}
 
 new_mtu:
-	mtu = tipc_node_get_mtu(dnode, tsk->port.ref);
+	mtu = tipc_node_get_mtu(dnode, tsk->ref);
 	rc = tipc_msg_build(mhdr, iov, 0, dsz, mtu, &buf);
 	if (rc < 0)
 		goto exit;
 
 	do {
 		TIPC_SKB_CB(buf)->wakeup_pending = tsk->link_cong;
-		rc = tipc_link_xmit(buf, dnode, tsk->port.ref);
+		rc = tipc_link_xmit(buf, dnode, tsk->ref);
 		if (likely(rc >= 0)) {
 			if (sock->state != SS_READY)
 				sock->state = SS_CONNECTING;
@@ -975,8 +1026,8 @@ static int tipc_wait_for_sndpkt(struct socket *sock, long *timeo_p)
 		prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
 		done = sk_wait_event(sk, timeo_p,
 				     (!tsk->link_cong &&
-				      !tipc_sk_conn_cong(tsk)) ||
-				     !tsk->port.connected);
+				      !tsk_conn_cong(tsk)) ||
+				     !tsk->connected);
 		finish_wait(sk_sleep(sk), &wait);
 	} while (!done);
 	return 0;
@@ -999,11 +1050,10 @@ static int tipc_send_stream(struct kiocb *iocb, struct socket *sock,
 {
 	struct sock *sk = sock->sk;
 	struct tipc_sock *tsk = tipc_sk(sk);
-	struct tipc_port *port = &tsk->port;
-	struct tipc_msg *mhdr = &port->phdr;
+	struct tipc_msg *mhdr = &tsk->phdr;
 	struct sk_buff *buf;
 	DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name);
-	u32 ref = port->ref;
+	u32 ref = tsk->ref;
 	int rc = -EINVAL;
 	long timeo;
 	u32 dnode;
@@ -1031,16 +1081,16 @@ static int tipc_send_stream(struct kiocb *iocb, struct socket *sock,
 	}
 
 	timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT);
-	dnode = tsk_peer_node(port);
+	dnode = tsk_peer_node(tsk);
 
 next:
-	mtu = port->max_pkt;
+	mtu = tsk->max_pkt;
 	send = min_t(uint, dsz - sent, TIPC_MAX_USER_MSG_SIZE);
 	rc = tipc_msg_build(mhdr, m->msg_iov, sent, send, mtu, &buf);
 	if (unlikely(rc < 0))
 		goto exit;
 	do {
-		if (likely(!tipc_sk_conn_cong(tsk))) {
+		if (likely(!tsk_conn_cong(tsk))) {
 			rc = tipc_link_xmit(buf, dnode, ref);
 			if (likely(!rc)) {
 				tsk->sent_unacked++;
@@ -1050,7 +1100,7 @@ next:
 				goto next;
 			}
 			if (rc == -EMSGSIZE) {
-				port->max_pkt = tipc_node_get_mtu(dnode, ref);
+				tsk->max_pkt = tipc_node_get_mtu(dnode, ref);
 				goto next;
 			}
 			if (rc != -ELINKCONG)
@@ -1089,10 +1139,10 @@ static int tipc_send_packet(struct kiocb *iocb, struct socket *sock,
 
 /* tipc_sk_finish_conn - complete the setup of a connection
  */
-static void tipc_sk_finish_conn(struct tipc_port *port, u32 peer_port,
+static void tipc_sk_finish_conn(struct tipc_sock *tsk, u32 peer_port,
 				u32 peer_node)
 {
-	struct tipc_msg *msg = &port->phdr;
+	struct tipc_msg *msg = &tsk->phdr;
 
 	msg_set_destnode(msg, peer_node);
 	msg_set_destport(msg, peer_port);
@@ -1100,12 +1150,12 @@ static void tipc_sk_finish_conn(struct tipc_port *port, u32 peer_port,
 	msg_set_lookup_scope(msg, 0);
 	msg_set_hdr_sz(msg, SHORT_H_SIZE);
 
-	port->probing_interval = CONN_PROBING_INTERVAL;
-	port->probing_state = TIPC_CONN_OK;
-	port->connected = 1;
-	k_start_timer(&port->timer, port->probing_interval);
-	tipc_node_add_conn(peer_node, port->ref, peer_port);
-	port->max_pkt = tipc_node_get_mtu(peer_node, port->ref);
+	tsk->probing_interval = CONN_PROBING_INTERVAL;
+	tsk->probing_state = TIPC_CONN_OK;
+	tsk->connected = 1;
+	k_start_timer(&tsk->timer, tsk->probing_interval);
+	tipc_node_add_conn(peer_node, tsk->ref, peer_port);
+	tsk->max_pkt = tipc_node_get_mtu(peer_node, tsk->ref);
 }
 
 /**
@@ -1132,17 +1182,17 @@ static void set_orig_addr(struct msghdr *m, struct tipc_msg *msg)
 }
 
 /**
- * anc_data_recv - optionally capture ancillary data for received message
+ * tipc_sk_anc_data_recv - optionally capture ancillary data for received message
  * @m: descriptor for message info
  * @msg: received message header
- * @tport: TIPC port associated with message
+ * @tsk: TIPC port associated with message
  *
  * Note: Ancillary data is not captured if not requested by receiver.
  *
  * Returns 0 if successful, otherwise errno
  */
-static int anc_data_recv(struct msghdr *m, struct tipc_msg *msg,
-			 struct tipc_port *tport)
+static int tipc_sk_anc_data_recv(struct msghdr *m, struct tipc_msg *msg,
+				 struct tipc_sock *tsk)
 {
 	u32 anc_data[3];
 	u32 err;
@@ -1185,10 +1235,10 @@ static int anc_data_recv(struct msghdr *m, struct tipc_msg *msg,
 		anc_data[2] = msg_nameupper(msg);
 		break;
 	case TIPC_CONN_MSG:
-		has_name = (tport->conn_type != 0);
-		anc_data[0] = tport->conn_type;
-		anc_data[1] = tport->conn_instance;
-		anc_data[2] = tport->conn_instance;
+		has_name = (tsk->conn_type != 0);
+		anc_data[0] = tsk->conn_type;
+		anc_data[1] = tsk->conn_instance;
+		anc_data[2] = tsk->conn_instance;
 		break;
 	default:
 		has_name = 0;
@@ -1202,17 +1252,17 @@ static int anc_data_recv(struct msghdr *m, struct tipc_msg *msg,
 	return 0;
 }
 
-static void tipc_sk_send_ack(struct tipc_port *port, uint ack)
+static void tipc_sk_send_ack(struct tipc_sock *tsk, uint ack)
 {
 	struct sk_buff *buf = NULL;
 	struct tipc_msg *msg;
-	u32 peer_port = tsk_peer_port(port);
-	u32 dnode = tsk_peer_node(port);
+	u32 peer_port = tsk_peer_port(tsk);
+	u32 dnode = tsk_peer_node(tsk);
 
-	if (!port->connected)
+	if (!tsk->connected)
 		return;
 	buf = tipc_msg_create(CONN_MANAGER, CONN_ACK, INT_H_SIZE, 0, dnode,
-			      tipc_own_addr, peer_port, port->ref, TIPC_OK);
+			      tipc_own_addr, peer_port, tsk->ref, TIPC_OK);
 	if (!buf)
 		return;
 	msg = buf_msg(buf);
@@ -1270,7 +1320,6 @@ static int tipc_recvmsg(struct kiocb *iocb, struct socket *sock,
 {
 	struct sock *sk = sock->sk;
 	struct tipc_sock *tsk = tipc_sk(sk);
-	struct tipc_port *port = &tsk->port;
 	struct sk_buff *buf;
 	struct tipc_msg *msg;
 	long timeo;
@@ -1313,7 +1362,7 @@ restart:
 	set_orig_addr(m, msg);
 
 	/* Capture ancillary data (optional) */
-	res = anc_data_recv(m, msg, port);
+	res = tipc_sk_anc_data_recv(m, msg, tsk);
 	if (res)
 		goto exit;
 
@@ -1340,7 +1389,7 @@ restart:
 	if (likely(!(flags & MSG_PEEK))) {
 		if ((sock->state != SS_READY) &&
 		    (++tsk->rcv_unacked >= TIPC_CONNACK_INTV)) {
-			tipc_sk_send_ack(port, tsk->rcv_unacked);
+			tipc_sk_send_ack(tsk, tsk->rcv_unacked);
 			tsk->rcv_unacked = 0;
 		}
 		tsk_advance_rx_queue(sk);
@@ -1367,7 +1416,6 @@ static int tipc_recv_stream(struct kiocb *iocb, struct socket *sock,
 {
 	struct sock *sk = sock->sk;
 	struct tipc_sock *tsk = tipc_sk(sk);
-	struct tipc_port *port = &tsk->port;
 	struct sk_buff *buf;
 	struct tipc_msg *msg;
 	long timeo;
@@ -1412,7 +1460,7 @@ restart:
 	/* Optionally capture sender's address & ancillary data of first msg */
 	if (sz_copied == 0) {
 		set_orig_addr(m, msg);
-		res = anc_data_recv(m, msg, port);
+		res = tipc_sk_anc_data_recv(m, msg, tsk);
 		if (res)
 			goto exit;
 	}
@@ -1451,7 +1499,7 @@ restart:
 	/* Consume received message (optional) */
 	if (likely(!(flags & MSG_PEEK))) {
 		if (unlikely(++tsk->rcv_unacked >= TIPC_CONNACK_INTV)) {
-			tipc_sk_send_ack(port, tsk->rcv_unacked);
+			tipc_sk_send_ack(tsk, tsk->rcv_unacked);
 			tsk->rcv_unacked = 0;
 		}
 		tsk_advance_rx_queue(sk);
@@ -1513,10 +1561,8 @@ static void tipc_data_ready(struct sock *sk)
 static int filter_connect(struct tipc_sock *tsk, struct sk_buff **buf)
 {
 	struct sock *sk = &tsk->sk;
-	struct tipc_port *port = &tsk->port;
 	struct socket *sock = sk->sk_socket;
 	struct tipc_msg *msg = buf_msg(*buf);
-
 	int retval = -TIPC_ERR_NO_PORT;
 
 	if (msg_mcast(msg))
@@ -1528,10 +1574,10 @@ static int filter_connect(struct tipc_sock *tsk, struct sk_buff **buf)
 		if (tsk_peer_msg(tsk, msg)) {
 			if (unlikely(msg_errcode(msg))) {
 				sock->state = SS_DISCONNECTING;
-				port->connected = 0;
+				tsk->connected = 0;
 				/* let timer expire on it's own */
-				tipc_node_remove_conn(tsk_peer_node(port),
-						      port->ref);
+				tipc_node_remove_conn(tsk_peer_node(tsk),
+						      tsk->ref);
 			}
 			retval = TIPC_OK;
 		}
@@ -1556,8 +1602,8 @@ static int filter_connect(struct tipc_sock *tsk, struct sk_buff **buf)
 			break;
 		}
 
-		tipc_sk_finish_conn(port, msg_origport(msg), msg_orignode(msg));
-		msg_set_importance(&port->phdr, msg_importance(msg));
+		tipc_sk_finish_conn(tsk, msg_origport(msg), msg_orignode(msg));
+		msg_set_importance(&tsk->phdr, msg_importance(msg));
 		sock->state = SS_CONNECTED;
 
 		/* If an incoming message is an 'ACK-', it should be
@@ -1715,7 +1761,6 @@ static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *buf)
 int tipc_sk_rcv(struct sk_buff *buf)
 {
 	struct tipc_sock *tsk;
-	struct tipc_port *port;
 	struct sock *sk;
 	u32 dport = msg_destport(buf_msg(buf));
 	int rc = TIPC_OK;
@@ -1728,7 +1773,6 @@ int tipc_sk_rcv(struct sk_buff *buf)
 		rc = tipc_msg_eval(buf, &dnode);
 		goto exit;
 	}
-	port = &tsk->port;
 	sk = &tsk->sk;
 
 	/* Queue message */
@@ -1931,7 +1975,7 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags)
 {
 	struct sock *new_sk, *sk = sock->sk;
 	struct sk_buff *buf;
-	struct tipc_port *new_port;
+	struct tipc_sock *new_tsock;
 	struct tipc_msg *msg;
 	long timeo;
 	int res;
@@ -1954,7 +1998,7 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags)
 		goto exit;
 
 	new_sk = new_sock->sk;
-	new_port = &tipc_sk(new_sk)->port;
+	new_tsock = tipc_sk(new_sk);
 	msg = buf_msg(buf);
 
 	/* we lock on new_sk; but lockdep sees the lock on sk */
@@ -1967,13 +2011,13 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags)
 	tsk_rej_rx_queue(new_sk);
 
 	/* Connect new socket to it's peer */
-	tipc_sk_finish_conn(new_port, msg_origport(msg), msg_orignode(msg));
+	tipc_sk_finish_conn(new_tsock, msg_origport(msg), msg_orignode(msg));
 	new_sock->state = SS_CONNECTED;
 
-	tsk_set_importance(new_port, msg_importance(msg));
+	tsk_set_importance(new_tsock, msg_importance(msg));
 	if (msg_named(msg)) {
-		new_port->conn_type = msg_nametype(msg);
-		new_port->conn_instance = msg_nameinst(msg);
+		new_tsock->conn_type = msg_nametype(msg);
+		new_tsock->conn_instance = msg_nameinst(msg);
 	}
 
 	/*
@@ -2009,7 +2053,6 @@ static int tipc_shutdown(struct socket *sock, int how)
 {
 	struct sock *sk = sock->sk;
 	struct tipc_sock *tsk = tipc_sk(sk);
-	struct tipc_port *port = &tsk->port;
 	struct sk_buff *buf;
 	u32 dnode;
 	int res;
@@ -2032,20 +2075,20 @@ restart:
 				goto restart;
 			}
 			if (tipc_msg_reverse(buf, &dnode, TIPC_CONN_SHUTDOWN))
-				tipc_link_xmit(buf, dnode, port->ref);
-			tipc_node_remove_conn(dnode, port->ref);
+				tipc_link_xmit(buf, dnode, tsk->ref);
+			tipc_node_remove_conn(dnode, tsk->ref);
 		} else {
-			dnode = tsk_peer_node(port);
+			dnode = tsk_peer_node(tsk);
 			buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE,
 					      TIPC_CONN_MSG, SHORT_H_SIZE,
 					      0, dnode, tipc_own_addr,
-					      tsk_peer_port(port),
-					      port->ref, TIPC_CONN_SHUTDOWN);
-			tipc_link_xmit(buf, dnode, port->ref);
+					      tsk_peer_port(tsk),
+					      tsk->ref, TIPC_CONN_SHUTDOWN);
+			tipc_link_xmit(buf, dnode, tsk->ref);
 		}
-		port->connected = 0;
+		tsk->connected = 0;
 		sock->state = SS_DISCONNECTING;
-		tipc_node_remove_conn(dnode, port->ref);
+		tipc_node_remove_conn(dnode, tsk->ref);
 		/* fall through */
 
 	case SS_DISCONNECTING:
@@ -2069,7 +2112,6 @@ restart:
 static void tipc_sk_timeout(unsigned long ref)
 {
 	struct tipc_sock *tsk;
-	struct tipc_port *port;
 	struct sock *sk;
 	struct sk_buff *buf = NULL;
 	u32 peer_port, peer_node;
@@ -2078,17 +2120,16 @@ static void tipc_sk_timeout(unsigned long ref)
 	if (!tsk)
 		goto exit;
 	sk = &tsk->sk;
-	port = &tsk->port;
 
 	bh_lock_sock(sk);
-	if (!port->connected) {
+	if (!tsk->connected) {
 		bh_unlock_sock(sk);
 		goto exit;
 	}
-	peer_port = tsk_peer_port(port);
-	peer_node = tsk_peer_node(port);
+	peer_port = tsk_peer_port(tsk);
+	peer_node = tsk_peer_node(tsk);
 
-	if (port->probing_state == TIPC_CONN_PROBING) {
+	if (tsk->probing_state == TIPC_CONN_PROBING) {
 		/* Previous probe not answered -> self abort */
 		buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG,
 				      SHORT_H_SIZE, 0, tipc_own_addr,
@@ -2098,8 +2139,8 @@ static void tipc_sk_timeout(unsigned long ref)
 		buf = tipc_msg_create(CONN_MANAGER, CONN_PROBE, INT_H_SIZE,
 				      0, peer_node, tipc_own_addr,
 				      peer_port, ref, TIPC_OK);
-		port->probing_state = TIPC_CONN_PROBING;
-		k_start_timer(&port->timer, port->probing_interval);
+		tsk->probing_state = TIPC_CONN_PROBING;
+		k_start_timer(&tsk->timer, tsk->probing_interval);
 	}
 	bh_unlock_sock(sk);
 	if (buf)
@@ -2108,37 +2149,37 @@ exit:
 	tipc_sk_put(tsk);
 }
 
-static int tipc_sk_publish(struct tipc_port *port, uint scope,
+static int tipc_sk_publish(struct tipc_sock *tsk, uint scope,
 			   struct tipc_name_seq const *seq)
 {
 	struct publication *publ;
 	u32 key;
 
-	if (port->connected)
+	if (tsk->connected)
 		return -EINVAL;
-	key = port->ref + port->pub_count + 1;
-	if (key == port->ref)
+	key = tsk->ref + tsk->pub_count + 1;
+	if (key == tsk->ref)
 		return -EADDRINUSE;
 
 	publ = tipc_nametbl_publish(seq->type, seq->lower, seq->upper,
-				    scope, port->ref, key);
+				    scope, tsk->ref, key);
 	if (unlikely(!publ))
 		return -EINVAL;
 
-	list_add(&publ->pport_list, &port->publications);
-	port->pub_count++;
-	port->published = 1;
+	list_add(&publ->pport_list, &tsk->publications);
+	tsk->pub_count++;
+	tsk->published = 1;
 	return 0;
 }
 
-static int tipc_sk_withdraw(struct tipc_port *port, uint scope,
+static int tipc_sk_withdraw(struct tipc_sock *tsk, uint scope,
 			    struct tipc_name_seq const *seq)
 {
 	struct publication *publ;
 	struct publication *safe;
 	int rc = -EINVAL;
 
-	list_for_each_entry_safe(publ, safe, &port->publications, pport_list) {
+	list_for_each_entry_safe(publ, safe, &tsk->publications, pport_list) {
 		if (seq) {
 			if (publ->scope != scope)
 				continue;
@@ -2157,12 +2198,12 @@ static int tipc_sk_withdraw(struct tipc_port *port, uint scope,
 				      publ->ref, publ->key);
 		rc = 0;
 	}
-	if (list_empty(&port->publications))
-		port->published = 0;
+	if (list_empty(&tsk->publications))
+		tsk->published = 0;
 	return rc;
 }
 
-static int tipc_sk_show(struct tipc_port *port, char *buf,
+static int tipc_sk_show(struct tipc_sock *tsk, char *buf,
 			int len, int full_id)
 {
 	struct publication *publ;
@@ -2172,26 +2213,26 @@ static int tipc_sk_show(struct tipc_port *port, char *buf,
 		ret = tipc_snprintf(buf, len, "<%u.%u.%u:%u>:",
 				    tipc_zone(tipc_own_addr),
 				    tipc_cluster(tipc_own_addr),
-				    tipc_node(tipc_own_addr), port->ref);
+				    tipc_node(tipc_own_addr), tsk->ref);
 	else
-		ret = tipc_snprintf(buf, len, "%-10u:", port->ref);
+		ret = tipc_snprintf(buf, len, "%-10u:", tsk->ref);
 
-	if (port->connected) {
-		u32 dport = tsk_peer_port(port);
-		u32 destnode = tsk_peer_node(port);
+	if (tsk->connected) {
+		u32 dport = tsk_peer_port(tsk);
+		u32 destnode = tsk_peer_node(tsk);
 
 		ret += tipc_snprintf(buf + ret, len - ret,
 				     " connected to <%u.%u.%u:%u>",
 				     tipc_zone(destnode),
 				     tipc_cluster(destnode),
 				     tipc_node(destnode), dport);
-		if (port->conn_type != 0)
+		if (tsk->conn_type != 0)
 			ret += tipc_snprintf(buf + ret, len - ret,
-					     " via {%u,%u}", port->conn_type,
-					     port->conn_instance);
-	} else if (port->published) {
+					     " via {%u,%u}", tsk->conn_type,
+					     tsk->conn_instance);
+	} else if (tsk->published) {
 		ret += tipc_snprintf(buf + ret, len - ret, " bound to");
-		list_for_each_entry(publ, &port->publications, pport_list) {
+		list_for_each_entry(publ, &tsk->publications, pport_list) {
 			if (publ->lower == publ->upper)
 				ret += tipc_snprintf(buf + ret, len - ret,
 						     " {%u,%u}", publ->type,
@@ -2226,7 +2267,7 @@ struct sk_buff *tipc_sk_socks_show(void)
 	tsk = tipc_sk_get_next(&ref);
 	for (; tsk; tsk = tipc_sk_get_next(&ref)) {
 		lock_sock(&tsk->sk);
-		str_len += tipc_sk_show(&tsk->port, pb + str_len,
+		str_len += tipc_sk_show(tsk, pb + str_len,
 					pb_len - str_len, 0);
 		release_sock(&tsk->sk);
 		tipc_sk_put(tsk);
@@ -2249,7 +2290,7 @@ void tipc_sk_reinit(void)
 
 	for (; tsk; tsk = tipc_sk_get_next(&ref)) {
 		lock_sock(&tsk->sk);
-		msg = &tsk->port.phdr;
+		msg = &tsk->phdr;
 		msg_set_prevnode(msg, tipc_own_addr);
 		msg_set_orignode(msg, tipc_own_addr);
 		release_sock(&tsk->sk);
@@ -2512,7 +2553,6 @@ static int tipc_setsockopt(struct socket *sock, int lvl, int opt,
 {
 	struct sock *sk = sock->sk;
 	struct tipc_sock *tsk = tipc_sk(sk);
-	struct tipc_port *port = &tsk->port;
 	u32 value;
 	int res;
 
@@ -2530,16 +2570,16 @@ static int tipc_setsockopt(struct socket *sock, int lvl, int opt,
 
 	switch (opt) {
 	case TIPC_IMPORTANCE:
-		res = tsk_set_importance(port, value);
+		res = tsk_set_importance(tsk, value);
 		break;
 	case TIPC_SRC_DROPPABLE:
 		if (sock->type != SOCK_STREAM)
-			tsk_set_unreliable(port, value);
+			tsk_set_unreliable(tsk, value);
 		else
 			res = -ENOPROTOOPT;
 		break;
 	case TIPC_DEST_DROPPABLE:
-		tsk_set_unreturnable(port, value);
+		tsk_set_unreturnable(tsk, value);
 		break;
 	case TIPC_CONN_TIMEOUT:
 		tipc_sk(sk)->conn_timeout = value;
@@ -2572,7 +2612,6 @@ static int tipc_getsockopt(struct socket *sock, int lvl, int opt,
 {
 	struct sock *sk = sock->sk;
 	struct tipc_sock *tsk = tipc_sk(sk);
-	struct tipc_port *port = &tsk->port;
 	int len;
 	u32 value;
 	int res;
@@ -2589,16 +2628,16 @@ static int tipc_getsockopt(struct socket *sock, int lvl, int opt,
 
 	switch (opt) {
 	case TIPC_IMPORTANCE:
-		value = tsk_importance(port);
+		value = tsk_importance(tsk);
 		break;
 	case TIPC_SRC_DROPPABLE:
-		value = tsk_unreliable(port);
+		value = tsk_unreliable(tsk);
 		break;
 	case TIPC_DEST_DROPPABLE:
-		value = tsk_unreturnable(port);
+		value = tsk_unreturnable(tsk);
 		break;
 	case TIPC_CONN_TIMEOUT:
-		value = tipc_sk(sk)->conn_timeout;
+		value = tsk->conn_timeout;
 		/* no need to set "res", since already 0 at this point */
 		break;
 	case TIPC_NODE_RECVQ_DEPTH:
diff --git a/net/tipc/socket.h b/net/tipc/socket.h
index 4877216..baa43d0 100644
--- a/net/tipc/socket.h
+++ b/net/tipc/socket.h
@@ -36,85 +36,11 @@
 #define _TIPC_SOCK_H
 
 #include <net/sock.h>
-#include "msg.h"
 
-#define TIPC_CONN_OK      0
-#define TIPC_CONN_PROBING 1
 #define TIPC_CONNACK_INTV         256
 #define TIPC_FLOWCTRL_WIN        (TIPC_CONNACK_INTV * 2)
 #define TIPC_CONN_OVERLOAD_LIMIT ((TIPC_FLOWCTRL_WIN * 2 + 1) * \
 				  SKB_TRUESIZE(TIPC_MAX_USER_MSG_SIZE))
-
-/**
- * struct tipc_port - TIPC port structure
- * @lock: pointer to spinlock for controlling access to port
- * @connected: non-zero if port is currently connected to a peer port
- * @conn_type: TIPC type used when connection was established
- * @conn_instance: TIPC instance used when connection was established
- * @published: non-zero if port has one or more associated names
- * @max_pkt: maximum packet size "hint" used when building messages sent by port
- * @ref: unique reference to port in TIPC object registry
- * @phdr: preformatted message header used when sending messages
- * @port_list: adjacent ports in TIPC's global list of ports
- * @publications: list of publications for port
- * @pub_count: total # of publications port has made during its lifetime
- * @probing_state:
- * @probing_interval:
- * @timer_ref:
- */
-struct tipc_port {
-	int connected;
-	u32 conn_type;
-	u32 conn_instance;
-	int published;
-	u32 max_pkt;
-	u32 ref;
-	struct tipc_msg phdr;
-	struct list_head port_list;
-	struct list_head publications;
-	u32 pub_count;
-	u32 probing_state;
-	u32 probing_interval;
-	struct timer_list timer;
-};
-
-/**
- * struct tipc_sock - TIPC socket structure
- * @sk: socket - interacts with 'port' and with user via the socket API
- * @port: port - interacts with 'sk' and with the rest of the TIPC stack
- * @peer_name: the peer of the connection, if any
- * @conn_timeout: the time we can wait for an unresponded setup request
- * @dupl_rcvcnt: number of bytes counted twice, in both backlog and rcv queue
- * @link_cong: non-zero if owner must sleep because of link congestion
- * @sent_unacked: # messages sent by socket, and not yet acked by peer
- * @rcv_unacked: # messages read by user, but not yet acked back to peer
- */
-
-struct tipc_sock {
-	struct sock sk;
-	struct tipc_port port;
-	unsigned int conn_timeout;
-	atomic_t dupl_rcvcnt;
-	bool link_cong;
-	uint sent_unacked;
-	uint rcv_unacked;
-};
-
-static inline struct tipc_sock *tipc_sk(const struct sock *sk)
-{
-	return container_of(sk, struct tipc_sock, sk);
-}
-
-static inline struct tipc_sock *tipc_port_to_sock(const struct tipc_port *port)
-{
-	return container_of(port, struct tipc_sock, port);
-}
-
-static inline int tipc_sk_conn_cong(struct tipc_sock *tsk)
-{
-	return tsk->sent_unacked >= TIPC_FLOWCTRL_WIN;
-}
-
 int tipc_sk_rcv(struct sk_buff *buf);
 struct sk_buff *tipc_sk_socks_show(void);
 void tipc_sk_mcast_rcv(struct sk_buff *buf);
-- 
1.7.9.5


------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [PATCH net-next 00/17] tipc: Merge port and socket layer code
  2014-08-22 22:09 [PATCH net-next 00/17] tipc: Merge port and socket layer code Jon Maloy
                   ` (16 preceding siblings ...)
  2014-08-22 22:09 ` [PATCH net-next 17/17] tipc: merge struct tipc_port into struct tipc_sock Jon Maloy
@ 2014-08-23 18:19 ` David Miller
  17 siblings, 0 replies; 22+ messages in thread
From: David Miller @ 2014-08-23 18:19 UTC (permalink / raw)
  To: jon.maloy
  Cc: netdev, paul.gortmaker, erik.hugne, ying.xue, maloy, tipc-discussion

From: Jon Maloy <jon.maloy@ericsson.com>
Date: Fri, 22 Aug 2014 18:09:03 -0400

> After the removal of the TIPC native interface, there is no reason to
> keep a distinction between a "generic" port layer and a "specific"
> socket layer in the code. Throughout the last months, we have posted
> several series that aimed at facilitating removal of the port layer,
> and in particular the port_lock spinlock, which in reality duplicates
> the role normally kept by lock_sock()/bh_lock_sock().
> 
> In this series, we finalize this work, by making a significant number of
> changes to the link, node, port and socket code, all with the aim of
> reducing dependencies between the layers. In the final commits, we then
> remove the port spinlock, port.c and port.h altogether.
> 
> After this series, we have a socket layer that has only few dependencies
> to the rest of the stack, so that it should be possible to continue
> cleanups of its code without significantly affecting other code.

Series applied, thanks Jon.

> It should be noted that commit ##1 and 2 are already in 'net' 
> (ac32c7f705692b92fe12dcbe88fe87136fdfff6f and 
> 02784f1b05b8f241c8180af88869e717e2758593), but not yet in net-next.
> Since they are prerequisites for the rest of the series to apply, I
> prepend them to the series.

I decided to handle this by merging 'net' into 'net-next' and then
just skipping those first two patches in the series.  Thanks for
letting me know about this dependency.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH net-next 02/17] tipc: Fix build.
  2014-08-22 22:09 ` [PATCH net-next 02/17] tipc: Fix build Jon Maloy
@ 2014-08-25 10:21   ` Neil Horman
  2014-08-25 18:44     ` David Miller
  0 siblings, 1 reply; 22+ messages in thread
From: Neil Horman @ 2014-08-25 10:21 UTC (permalink / raw)
  To: Jon Maloy
  Cc: davem, netdev, Paul Gortmaker, erik.hugne, ying.xue, maloy,
	tipc-discussion

On Fri, Aug 22, 2014 at 06:09:05PM -0400, Jon Maloy wrote:
> From: "David S. Miller" <davem@davemloft.net>
> 
> Missing semicolon in range check fix.
> 
> Signed-off-by: David S. Miller <davem@davemloft.net>
> Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
> ---
>  net/tipc/port.h |    3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/net/tipc/port.h b/net/tipc/port.h
> index a69118f..3087da3 100644
> --- a/net/tipc/port.h
> +++ b/net/tipc/port.h
> @@ -182,8 +182,9 @@ static inline int tipc_port_importance(struct tipc_port *port)
>  static inline int tipc_port_set_importance(struct tipc_port *port, int imp)
>  {
>  	if (imp > TIPC_CRITICAL_IMPORTANCE)
> -		return -EINVAL
> +		return -EINVAL;
>  	msg_set_importance(&port->phdr, (u32)imp);
> +	return 0;
>  }
>  
Fold this in with the previous patch to avoid a FTBFS during a bisect.
Neil

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH net-next 02/17] tipc: Fix build.
  2014-08-25 10:21   ` Neil Horman
@ 2014-08-25 18:44     ` David Miller
  2014-08-26 13:15       ` Neil Horman
  0 siblings, 1 reply; 22+ messages in thread
From: David Miller @ 2014-08-25 18:44 UTC (permalink / raw)
  To: nhorman
  Cc: jon.maloy, netdev, paul.gortmaker, erik.hugne, ying.xue, maloy,
	tipc-discussion

From: Neil Horman <nhorman@tuxdriver.com>
Date: Mon, 25 Aug 2014 06:21:42 -0400

> On Fri, Aug 22, 2014 at 06:09:05PM -0400, Jon Maloy wrote:
>> From: "David S. Miller" <davem@davemloft.net>
>> 
>> Missing semicolon in range check fix.
>> 
>> Signed-off-by: David S. Miller <davem@davemloft.net>
>> Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
>> ---
>>  net/tipc/port.h |    3 ++-
>>  1 file changed, 2 insertions(+), 1 deletion(-)
>> 
>> diff --git a/net/tipc/port.h b/net/tipc/port.h
>> index a69118f..3087da3 100644
>> --- a/net/tipc/port.h
>> +++ b/net/tipc/port.h
>> @@ -182,8 +182,9 @@ static inline int tipc_port_importance(struct tipc_port *port)
>>  static inline int tipc_port_set_importance(struct tipc_port *port, int imp)
>>  {
>>  	if (imp > TIPC_CRITICAL_IMPORTANCE)
>> -		return -EINVAL
>> +		return -EINVAL;
>>  	msg_set_importance(&port->phdr, (u32)imp);
>> +	return 0;
>>  }
>>  
> Fold this in with the previous patch to avoid a FTBFS during a bisect.

See his header posting, these are changes already in mainline that hadn't
hit net-next yet.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH net-next 02/17] tipc: Fix build.
  2014-08-25 18:44     ` David Miller
@ 2014-08-26 13:15       ` Neil Horman
  0 siblings, 0 replies; 22+ messages in thread
From: Neil Horman @ 2014-08-26 13:15 UTC (permalink / raw)
  To: David Miller
  Cc: jon.maloy, netdev, paul.gortmaker, erik.hugne, ying.xue, maloy,
	tipc-discussion

On Mon, Aug 25, 2014 at 11:44:20AM -0700, David Miller wrote:
> From: Neil Horman <nhorman@tuxdriver.com>
> Date: Mon, 25 Aug 2014 06:21:42 -0400
> 
> > On Fri, Aug 22, 2014 at 06:09:05PM -0400, Jon Maloy wrote:
> >> From: "David S. Miller" <davem@davemloft.net>
> >> 
> >> Missing semicolon in range check fix.
> >> 
> >> Signed-off-by: David S. Miller <davem@davemloft.net>
> >> Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
> >> ---
> >>  net/tipc/port.h |    3 ++-
> >>  1 file changed, 2 insertions(+), 1 deletion(-)
> >> 
> >> diff --git a/net/tipc/port.h b/net/tipc/port.h
> >> index a69118f..3087da3 100644
> >> --- a/net/tipc/port.h
> >> +++ b/net/tipc/port.h
> >> @@ -182,8 +182,9 @@ static inline int tipc_port_importance(struct tipc_port *port)
> >>  static inline int tipc_port_set_importance(struct tipc_port *port, int imp)
> >>  {
> >>  	if (imp > TIPC_CRITICAL_IMPORTANCE)
> >> -		return -EINVAL
> >> +		return -EINVAL;
> >>  	msg_set_importance(&port->phdr, (u32)imp);
> >> +	return 0;
> >>  }
> >>  
> > Fold this in with the previous patch to avoid a FTBFS during a bisect.
> 
> See his header posting, these are changes already in mainline that hadn't
> hit net-next yet.
My bad, thanks
Neil

> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2014-08-26 13:16 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-22 22:09 [PATCH net-next 00/17] tipc: Merge port and socket layer code Jon Maloy
2014-08-22 22:09 ` [PATCH net-next 01/17] tipc: fix message importance range check Jon Maloy
2014-08-22 22:09 ` [PATCH net-next 02/17] tipc: Fix build Jon Maloy
2014-08-25 10:21   ` Neil Horman
2014-08-25 18:44     ` David Miller
2014-08-26 13:15       ` Neil Horman
2014-08-22 22:09 ` [PATCH net-next 03/17] tipc: introduce new function tipc_msg_create() Jon Maloy
2014-08-22 22:09 ` [PATCH net-next 04/17] tipc: use pseudo message to wake up sockets after link congestion Jon Maloy
2014-08-22 22:09 ` [PATCH net-next 05/17] tipc: use message to abort connections when losing contact to node Jon Maloy
2014-08-22 22:09 ` [PATCH net-next 06/17] tipc: clean up socket timer function Jon Maloy
2014-08-22 22:09 ` [PATCH net-next 07/17] tipc: eliminate function tipc_port_shutdown() Jon Maloy
2014-08-22 22:09 ` [PATCH net-next 08/17] tipc: eliminate port_connect()/port_disconnect() functions Jon Maloy
2014-08-22 22:09 ` [PATCH net-next 09/17] tipc: redefine message acknowledge function Jon Maloy
2014-08-22 22:09 ` [PATCH net-next 10/17] tipc: eliminate functions tipc_port_init and tipc_port_destroy Jon Maloy
2014-08-22 22:09 ` [PATCH net-next 11/17] tipc: use registry when scanning sockets Jon Maloy
2014-08-22 22:09 ` [PATCH net-next 12/17] tipc: replace port pointer with socket pointer in registry Jon Maloy
2014-08-22 22:09 ` [PATCH net-next 13/17] tipc: remove port_lock Jon Maloy
2014-08-22 22:09 ` [PATCH net-next 14/17] tipc: remove source file port.c Jon Maloy
2014-08-22 22:09 ` [PATCH net-next 15/17] tipc: remove include file port.h Jon Maloy
2014-08-22 22:09 ` [PATCH net-next 16/17] tipc: remove files ref.h and ref.c Jon Maloy
2014-08-22 22:09 ` [PATCH net-next 17/17] tipc: merge struct tipc_port into struct tipc_sock Jon Maloy
2014-08-23 18:19 ` [PATCH net-next 00/17] tipc: Merge port and socket layer code David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.