tipc: aggregate port structure into socket structure
authorJon Paul Maloy <jon.maloy@ericsson.com>
Wed, 12 Mar 2014 15:31:09 +0000 (11:31 -0400)
committerDavid S. Miller <davem@davemloft.net>
Wed, 12 Mar 2014 19:53:49 +0000 (15:53 -0400)
After the removal of the tipc native API the relation between
a tipc_port and its API types is strictly one-to-one, i.e, the
latter can now only be a socket API. There is therefore no need
to allocate struct tipc_port and struct sock independently.

In this commit, we aggregate struct tipc_port into struct tipc_sock,
hence saving both CPU cycles and structure complexity.

There are no functional changes in this commit, except for the
elimination of the separate allocation/freeing of tipc_port.
All other changes are just adaptatons to the new data structure.

This commit also opens up for further code simplifications and
code volume reduction, something we will do in later commits.

Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Reviewed-by: Ying Xue <ying.xue@windriver.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/tipc/port.c
net/tipc/port.h
net/tipc/socket.c
net/tipc/socket.h [new file with mode: 0644]

index d1abe11041209b7a20e35e7c3d65f1f4b0644b39..7b027e99a5c945e2c96d7c95581905322a195897 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * net/tipc/port.c: TIPC port code
  *
- * Copyright (c) 1992-2007, Ericsson AB
+ * Copyright (c) 1992-2007, 2014, Ericsson AB
  * Copyright (c) 2004-2008, 2010-2013, Wind River Systems
  * All rights reserved.
  *
@@ -38,6 +38,7 @@
 #include "config.h"
 #include "port.h"
 #include "name_table.h"
+#include "socket.h"
 
 /* Connection management: */
 #define PROBING_INTERVAL 3600000       /* [ms] => 1 h */
@@ -200,23 +201,16 @@ struct tipc_port *tipc_createport(struct sock *sk,
                                  void (*wakeup)(struct tipc_port *),
                                  const u32 importance)
 {
-       struct tipc_port *p_ptr;
+       struct tipc_port *p_ptr = tipc_sk_port(sk);
        struct tipc_msg *msg;
        u32 ref;
 
-       p_ptr = kzalloc(sizeof(*p_ptr), GFP_ATOMIC);
-       if (!p_ptr) {
-               pr_warn("Port creation failed, no memory\n");
-               return NULL;
-       }
        ref = tipc_ref_acquire(p_ptr, &p_ptr->lock);
        if (!ref) {
-               pr_warn("Port creation failed, ref. table exhausted\n");
-               kfree(p_ptr);
+               pr_warn("Port registration failed, ref. table exhausted\n");
                return NULL;
        }
 
-       p_ptr->sk = sk;
        p_ptr->max_pkt = MAX_PKT_DEFAULT;
        p_ptr->ref = ref;
        INIT_LIST_HEAD(&p_ptr->wait_list);
@@ -262,7 +256,6 @@ int tipc_deleteport(struct tipc_port *p_ptr)
        list_del(&p_ptr->wait_list);
        spin_unlock_bh(&tipc_port_list_lock);
        k_term_timer(&p_ptr->timer);
-       kfree(p_ptr);
        tipc_net_route_msg(buf);
        return 0;
 }
index 4a2a1ac8686c823944192cae7be32064da850b25..1b200624bfbd8d54f9bd15ec45d3c220cdbe6278 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * net/tipc/port.h: Include file for TIPC port code
  *
- * Copyright (c) 1994-2007, Ericsson AB
+ * Copyright (c) 1994-2007, 2014, Ericsson AB
  * Copyright (c) 2004-2007, 2010-2013, Wind River Systems
  * All rights reserved.
  *
@@ -48,7 +48,6 @@
 
 /**
  * struct tipc_port - TIPC port structure
- * @sk: pointer to socket handle
  * @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
@@ -74,7 +73,6 @@
  * @subscription: "node down" subscription used to terminate failed connections
  */
 struct tipc_port {
-       struct sock *sk;
        spinlock_t *lock;
        int connected;
        u32 conn_type;
index 62655772adda72933c299f00e3c1a45309df060d..912665d409de256bddb30b4d47f41b8f597d4ab8 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * net/tipc/socket.c: TIPC socket API
  *
- * Copyright (c) 2001-2007, 2012 Ericsson AB
+ * Copyright (c) 2001-2007, 2012-2014, Ericsson AB
  * Copyright (c) 2004-2008, 2010-2013, Wind River Systems
  * All rights reserved.
  *
 #include "port.h"
 
 #include <linux/export.h>
-#include <net/sock.h>
 
 #define SS_LISTENING   -1      /* socket is listening */
 #define SS_READY       -2      /* socket is connectionless */
 
 #define CONN_TIMEOUT_DEFAULT   8000    /* default connect timeout = 8s */
 
-struct tipc_sock {
-       struct sock sk;
-       struct tipc_port *p;
-       unsigned int conn_timeout;
-};
-
-#define tipc_sk(sk) ((struct tipc_sock *)(sk))
-#define tipc_sk_port(sk) (tipc_sk(sk)->p)
 
 static int backlog_rcv(struct sock *sk, struct sk_buff *skb);
 static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf);
@@ -114,6 +105,8 @@ static struct proto tipc_proto_kern;
  *   - port reference
  */
 
+#include "socket.h"
+
 /**
  * advance_rx_queue - discard first buffer in socket receive queue
  *
@@ -205,7 +198,6 @@ static int tipc_sk_create(struct net *net, struct socket *sock, int protocol,
        sk->sk_rcvbuf = sysctl_tipc_rmem[1];
        sk->sk_data_ready = tipc_data_ready;
        sk->sk_write_space = tipc_write_space;
-       tipc_sk(sk)->p = tp_ptr;
        tipc_sk(sk)->conn_timeout = CONN_TIMEOUT_DEFAULT;
 
        spin_unlock_bh(tp_ptr->lock);
@@ -437,18 +429,17 @@ static int tipc_getname(struct socket *sock, struct sockaddr *uaddr,
                        int *uaddr_len, int peer)
 {
        struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr;
-       struct tipc_sock *tsock = tipc_sk(sock->sk);
+       struct tipc_port *port = tipc_sk_port(sock->sk);
 
        memset(addr, 0, sizeof(*addr));
        if (peer) {
                if ((sock->state != SS_CONNECTED) &&
                        ((peer != 2) || (sock->state != SS_DISCONNECTING)))
                        return -ENOTCONN;
-
-               addr->addr.id.ref = tipc_port_peerport(tsock->p);
-               addr->addr.id.node = tipc_port_peernode(tsock->p);
+               addr->addr.id.ref = tipc_port_peerport(port);
+               addr->addr.id.node = tipc_port_peernode(port);
        } else {
-               addr->addr.id.ref = tsock->p->ref;
+               addr->addr.id.ref = port->ref;
                addr->addr.id.node = tipc_own_addr;
        }
 
@@ -879,14 +870,13 @@ exit:
  */
 static int auto_connect(struct socket *sock, struct tipc_msg *msg)
 {
-       struct tipc_sock *tsock = tipc_sk(sock->sk);
-       struct tipc_port *p_ptr;
+       struct tipc_port *p_ptr = tipc_sk_port(sock->sk);
        struct tipc_portid peer;
 
        peer.ref = msg_origport(msg);
        peer.node = msg_orignode(msg);
 
-       p_ptr = tipc_port_deref(tsock->p->ref);
+       p_ptr = tipc_port_deref(p_ptr->ref);
        if (!p_ptr)
                return -EINVAL;
 
@@ -1270,17 +1260,18 @@ static void tipc_data_ready(struct sock *sk, int len)
 
 /**
  * filter_connect - Handle all incoming messages for a connection-based socket
- * @tsock: TIPC socket
+ * @port: TIPC port
  * @msg: message
  *
  * Returns TIPC error status code and socket error status code
  * once it encounters some errors
  */
-static u32 filter_connect(struct tipc_sock *tsock, struct sk_buff **buf)
+static u32 filter_connect(struct tipc_port *port, struct sk_buff **buf)
 {
-       struct socket *sock = tsock->sk.sk_socket;
+       struct sock *sk = tipc_port_to_sk(port);
+       struct socket *sock = sk->sk_socket;
        struct tipc_msg *msg = buf_msg(*buf);
-       struct sock *sk = &tsock->sk;
+
        u32 retval = TIPC_ERR_NO_PORT;
        int res;
 
@@ -1290,10 +1281,10 @@ static u32 filter_connect(struct tipc_sock *tsock, 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(tsock->p, msg)) {
+               if (msg_connected(msg) && tipc_port_peer_msg(port, msg)) {
                        if (unlikely(msg_errcode(msg))) {
                                sock->state = SS_DISCONNECTING;
-                               __tipc_port_disconnect(tsock->p);
+                               __tipc_port_disconnect(port);
                        }
                        retval = TIPC_OK;
                }
@@ -1401,7 +1392,7 @@ static u32 filter_rcv(struct sock *sk, struct sk_buff *buf)
                if (msg_connected(msg))
                        return TIPC_ERR_NO_PORT;
        } else {
-               res = filter_connect(tipc_sk(sk), &buf);
+               res = filter_connect(tipc_sk_port(sk), &buf);
                if (res != TIPC_OK || buf == NULL)
                        return res;
        }
@@ -1447,9 +1438,9 @@ static int backlog_rcv(struct sock *sk, struct sk_buff *buf)
  *
  * Returns TIPC error status code (TIPC_OK if message is not to be rejected)
  */
-static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf)
+static u32 dispatch(struct tipc_port *port, struct sk_buff *buf)
 {
-       struct sock *sk = tport->sk;
+       struct sock *sk = tipc_port_to_sk(port);
        u32 res;
 
        /*
@@ -1478,10 +1469,9 @@ static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf)
  *
  * Called with port lock already taken.
  */
-static void wakeupdispatch(struct tipc_port *tport)
+static void wakeupdispatch(struct tipc_port *port)
 {
-       struct sock *sk = tport->sk;
-
+       struct sock *sk = tipc_port_to_sk(port);
        sk->sk_write_space(sk);
 }
 
@@ -1661,8 +1651,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_sock *new_tsock;
-       struct tipc_port *new_tport;
+       struct tipc_port *new_port;
        struct tipc_msg *msg;
        struct tipc_portid peer;
        u32 new_ref;
@@ -1675,7 +1664,6 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags)
                res = -EINVAL;
                goto exit;
        }
-
        timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
        res = tipc_wait_for_accept(sock, timeo);
        if (res)
@@ -1688,9 +1676,8 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags)
                goto exit;
 
        new_sk = new_sock->sk;
-       new_tsock = tipc_sk(new_sk);
-       new_tport = new_tsock->p;
-       new_ref = new_tport->ref;
+       new_port = tipc_sk_port(new_sk);
+       new_ref = new_port->ref;
        msg = buf_msg(buf);
 
        /* we lock on new_sk; but lockdep sees the lock on sk */
@@ -1710,8 +1697,8 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags)
 
        tipc_set_portimportance(new_ref, msg_importance(msg));
        if (msg_named(msg)) {
-               new_tport->conn_type = msg_nametype(msg);
-               new_tport->conn_instance = msg_nameinst(msg);
+               new_port->conn_type = msg_nametype(msg);
+               new_port->conn_instance = msg_nameinst(msg);
        }
 
        /*
@@ -1729,7 +1716,6 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags)
                skb_set_owner_r(buf, new_sk);
        }
        release_sock(new_sk);
-
 exit:
        release_sock(sk);
        return res;
diff --git a/net/tipc/socket.h b/net/tipc/socket.h
new file mode 100644 (file)
index 0000000..f1cd54a
--- /dev/null
@@ -0,0 +1,70 @@
+/* net/tipc/socket.h: Include file for TIPC socket code
+ *
+ * Copyright (c) 2014, Ericsson AB
+ * 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_SOCK_H
+#define _TIPC_SOCK_H
+
+#include "port.h"
+#include <net/sock.h>
+
+/**
+ * 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
+ */
+
+struct tipc_sock {
+       struct sock sk;
+       struct tipc_port port;
+       unsigned int conn_timeout;
+};
+
+static inline struct tipc_sock *tipc_sk(const struct sock *sk)
+{
+       return container_of(sk, struct tipc_sock, sk);
+}
+
+static inline struct tipc_port *tipc_sk_port(const struct sock *sk)
+{
+       return &(tipc_sk(sk)->port);
+}
+
+static inline struct sock *tipc_port_to_sk(const struct tipc_port *port)
+{
+       return &(container_of(port, struct tipc_sock, port))->sk;
+}
+
+#endif