remove extra parentheses in return statement
[dpdk.git] / lib / librte_eal / linuxapp / kni / kni_vhost.c
index fefc98c..6f2a961 100644 (file)
@@ -1,23 +1,23 @@
 /*-
  * GPL LICENSE SUMMARY
- * 
- *   Copyright(c) 2010-2013 Intel Corporation. All rights reserved.
- * 
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of version 2 of the GNU General Public License as
  *   published by the Free Software Foundation.
- * 
+ *
  *   This program is distributed in the hope that it will be useful, but
  *   WITHOUT ANY WARRANTY; without even the implied warranty of
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  *   General Public License for more details.
- * 
+ *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
  *   Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  *   The full GNU General Public License is included in this distribution
  *   in the file called LICENSE.GPL.
- * 
+ *
  *   Contact Information:
  *   Intel Corporation
  */
 #include <linux/nsproxy.h>
 #include <linux/sched.h>
 #include <linux/if_tun.h>
+#include <linux/version.h>
 
-#include "kni_dev.h" 
+#include "compat.h"
+#include "kni_dev.h"
 #include "kni_fifo.h"
 
 #define RX_BURST_SZ 4
 
 extern void put_unused_fd(unsigned int fd);
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
+extern struct file*
+sock_alloc_file(struct socket *sock,
+               int flags, const char *dname);
+
+extern int get_unused_fd_flags(unsigned flags);
+
+extern void fd_install(unsigned int fd, struct file *file);
+
+static int kni_sock_map_fd(struct socket *sock)
+{
+       struct file *file;
+       int fd = get_unused_fd_flags(0);
+       if (fd < 0)
+               return fd;
+
+       file = sock_alloc_file(sock, 0, NULL);
+       if (IS_ERR(file)) {
+               put_unused_fd(fd);
+               return PTR_ERR(file);
+       }
+       fd_install(fd, file);
+       return fd;
+}
+#else
+#define kni_sock_map_fd(s)             sock_map_fd(s, 0)
+#endif
+
 static struct proto kni_raw_proto = {
        .name = "kni_vhost",
        .owner = THIS_MODULE,
@@ -46,15 +76,19 @@ static struct proto kni_raw_proto = {
 };
 
 static inline int
-kni_vhost_net_tx(struct kni_dev *kni, struct iovec *iov, 
+kni_vhost_net_tx(struct kni_dev *kni, struct msghdr *m,
                 unsigned offset, unsigned len)
 {
        struct rte_kni_mbuf *pkt_kva = NULL;
        struct rte_kni_mbuf *pkt_va = NULL;
        int ret;
 
-       KNI_DBG_TX("tx offset=%d, len=%d, iovlen=%d\n", 
-                  offset, len, (int)iov->iov_len);
+       KNI_DBG_TX("tx offset=%d, len=%d, iovlen=%d\n",
+#ifdef HAVE_IOV_ITER_MSGHDR
+                  offset, len, (int)m->msg_iter.iov->iov_len);
+#else
+                  offset, len, (int)m->msg_iov->iov_len);
+#endif
 
        /**
         * Check if it has at least one free entry in tx_q and
@@ -75,9 +109,15 @@ kni_vhost_net_tx(struct kni_dev *kni, struct iovec *iov,
                void *data_kva;
 
                pkt_kva = (void *)pkt_va - kni->mbuf_va + kni->mbuf_kva;
-               data_kva = pkt_kva->data - kni->mbuf_va + kni->mbuf_kva;
+               data_kva = pkt_kva->buf_addr + pkt_kva->data_off
+                          - kni->mbuf_va + kni->mbuf_kva;
+
+#ifdef HAVE_IOV_ITER_MSGHDR
+               copy_from_iter(data_kva, len, &m->msg_iter);
+#else
+               memcpy_fromiovecend(data_kva, m->msg_iov, offset, len);
+#endif
 
-               memcpy_fromiovecend(data_kva, iov, offset, len);
                if (unlikely(len < ETH_ZLEN)) {
                        memset(data_kva + len, 0, ETH_ZLEN - len);
                        len = ETH_ZLEN;
@@ -112,7 +152,7 @@ drop:
 }
 
 static inline int
-kni_vhost_net_rx(struct kni_dev *kni, struct iovec *iov, 
+kni_vhost_net_rx(struct kni_dev *kni, struct msghdr *m,
                 unsigned offset, unsigned len)
 {
        uint32_t pkt_len;
@@ -134,7 +174,7 @@ kni_vhost_net_rx(struct kni_dev *kni, struct iovec *iov,
                return 0;
 
        kva = (struct rte_kni_mbuf*)skb->data;
-       
+
        /* free skb to cache */
        skb->data = NULL;
        if (unlikely(1 != kni_fifo_put(q->fifo, (void **)&skb, 1)))
@@ -145,16 +185,24 @@ kni_vhost_net_rx(struct kni_dev *kni, struct iovec *iov,
        if (unlikely(pkt_len > len))
                goto drop;
 
-       KNI_DBG_RX("rx offset=%d, len=%d, pkt_len=%d, iovlen=%d\n", 
-                  offset, len, pkt_len, (int)iov->iov_len);
+       KNI_DBG_RX("rx offset=%d, len=%d, pkt_len=%d, iovlen=%d\n",
+#ifdef HAVE_IOV_ITER_MSGHDR
+                  offset, len, pkt_len, (int)m->msg_iter.iov->iov_len);
+#else
+                  offset, len, pkt_len, (int)m->msg_iov->iov_len);
+#endif
 
-       data_kva = kva->data - kni->mbuf_va + kni->mbuf_kva;            
-       if (unlikely(memcpy_toiovecend(iov, data_kva, offset, pkt_len)))
+       data_kva = kva->buf_addr + kva->data_off - kni->mbuf_va + kni->mbuf_kva;
+#ifdef HAVE_IOV_ITER_MSGHDR
+       if (unlikely(copy_to_iter(data_kva, pkt_len, &m->msg_iter)))
+#else
+       if (unlikely(memcpy_toiovecend(m->msg_iov, data_kva, offset, pkt_len)))
+#endif
                goto drop;
 
        /* Update statistics */
        kni->stats.rx_bytes += pkt_len;
-       kni->stats.rx_packets++;        
+       kni->stats.rx_packets++;
 
        /* enqueue mbufs into free_q */
        va = (void*)kva - kni->mbuf_kva + kni->mbuf_va;
@@ -173,10 +221,10 @@ drop:
        return 0;
 }
 
-static unsigned int 
+static unsigned int
 kni_sock_poll(struct file *file, struct socket *sock, poll_table * wait)
 {
-       struct kni_vhost_queue *q = 
+       struct kni_vhost_queue *q =
                container_of(sock->sk, struct kni_vhost_queue, sk);
        struct kni_dev *kni;
        unsigned int mask = 0;
@@ -185,10 +233,19 @@ kni_sock_poll(struct file *file, struct socket *sock, poll_table * wait)
                return POLLERR;
 
        kni = q->kni;
-       KNI_DBG("start kni_poll on group %d, wq 0x%16llx\n", 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)
+       KNI_DBG("start kni_poll on group %d, wq 0x%16llx\n",
                  kni->group_id, (uint64_t)sock->wq);
+#else
+       KNI_DBG("start kni_poll on group %d, wait at 0x%16llx\n",
+                 kni->group_id, (uint64_t)&sock->wait);
+#endif
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)
        poll_wait(file, &sock->wq->wait, wait);
+#else
+       poll_wait(file, &sock->wait, wait);
+#endif
 
        if (kni_fifo_count(kni->rx_q) > 0)
                mask |= POLLIN | POLLRDNORM;
@@ -202,19 +259,19 @@ kni_sock_poll(struct file *file, struct socket *sock, poll_table * wait)
 }
 
 static inline void
-kni_vhost_enqueue(struct kni_dev *kni, struct kni_vhost_queue *q, 
+kni_vhost_enqueue(struct kni_dev *kni, struct kni_vhost_queue *q,
                  struct sk_buff *skb, struct rte_kni_mbuf *va)
 {
        struct rte_kni_mbuf *kva;
 
-       kva = (void *)(va) - kni->mbuf_va + kni->mbuf_kva;             
+       kva = (void *)(va) - kni->mbuf_va + kni->mbuf_kva;
        (skb)->data = (unsigned char*)kva;
        (skb)->len = kva->data_len;
-       skb_queue_tail(&q->sk.sk_receive_queue, skb);   
+       skb_queue_tail(&q->sk.sk_receive_queue, skb);
 }
 
-static inline void 
-kni_vhost_enqueue_burst(struct kni_dev *kni, struct kni_vhost_queue *q, 
+static inline void
+kni_vhost_enqueue_burst(struct kni_dev *kni, struct kni_vhost_queue *q,
          struct sk_buff **skb, struct rte_kni_mbuf **va)
 {
        int i;
@@ -222,7 +279,7 @@ kni_vhost_enqueue_burst(struct kni_dev *kni, struct kni_vhost_queue *q,
                kni_vhost_enqueue(kni, q, *skb, *va);
 }
 
-int 
+int
 kni_chk_vhost_rx(struct kni_dev *kni)
 {
        struct kni_vhost_queue *q = kni->vhost_queue;
@@ -231,7 +288,7 @@ kni_chk_vhost_rx(struct kni_dev *kni)
        unsigned nb_burst, nb_backlog, i;
        struct sk_buff *skb[RX_BURST_SZ];
        struct rte_kni_mbuf *va[RX_BURST_SZ];
-       
+
        if (unlikely(BE_STOP & kni->vq_status)) {
                kni->vq_status |= BE_FINISH;
                return 0;
@@ -242,21 +299,21 @@ kni_chk_vhost_rx(struct kni_dev *kni)
 
        nb_skb = kni_fifo_count(q->fifo);
        nb_mbuf = kni_fifo_count(kni->rx_q);
-       
+
        nb_in = min(nb_mbuf, nb_skb);
        nb_in = min(nb_in, (unsigned)RX_BURST_SZ);
        nb_burst   = (nb_in & ~BURST_MASK);
        nb_backlog = (nb_in & BURST_MASK);
-       
+
        /* enqueue skb_queue per BURST_SIZE bulk */
        if (0 != nb_burst) {
                if (unlikely(RX_BURST_SZ != kni_fifo_get(
-                                    kni->rx_q, (void **)&va, 
+                                    kni->rx_q, (void **)&va,
                                     RX_BURST_SZ)))
                        goto except;
 
                if (unlikely(RX_BURST_SZ != kni_fifo_get(
-                                    q->fifo, (void **)&skb, 
+                                    q->fifo, (void **)&skb,
                                     RX_BURST_SZ)))
                        goto except;
 
@@ -277,11 +334,11 @@ kni_chk_vhost_rx(struct kni_dev *kni)
        }
 
        /* Ondemand wake up */
-       if ((nb_in == RX_BURST_SZ) || (nb_skb == 0) || 
-           ((nb_mbuf < RX_BURST_SZ) && (nb_mbuf != 0))) { 
-               wake_up_interruptible_poll(sk_sleep(&q->sk), 
+       if ((nb_in == RX_BURST_SZ) || (nb_skb == 0) ||
+           ((nb_mbuf < RX_BURST_SZ) && (nb_mbuf != 0))) {
+               wake_up_interruptible_poll(sk_sleep(&q->sk),
                                   POLLIN | POLLRDNORM | POLLRDBAND);
-               KNI_DBG_RX("RX CHK KICK nb_mbuf %d, nb_skb %d, nb_in %d\n", 
+               KNI_DBG_RX("RX CHK KICK nb_mbuf %d, nb_skb %d, nb_in %d\n",
                           nb_mbuf, nb_skb, nb_in);
        }
 
@@ -295,11 +352,16 @@ except:
        return 0;
 }
 
-static int 
+static int
+#ifdef HAVE_KIOCB_MSG_PARAM
 kni_sock_sndmsg(struct kiocb *iocb, struct socket *sock,
           struct msghdr *m, size_t total_len)
+#else
+kni_sock_sndmsg(struct socket *sock,
+          struct msghdr *m, size_t total_len)
+#endif /* HAVE_KIOCB_MSG_PARAM */
 {
-       struct kni_vhost_queue *q = 
+       struct kni_vhost_queue *q =
                container_of(sock->sk, struct kni_vhost_queue, sk);
        int vnet_hdr_len = 0;
        unsigned long len = total_len;
@@ -307,8 +369,12 @@ kni_sock_sndmsg(struct kiocb *iocb, struct socket *sock,
        if (unlikely(q == NULL || q->kni == NULL))
                return 0;
 
-       KNI_DBG_TX("kni_sndmsg len %ld, flags 0x%08x, nb_iov %d\n", 
+       KNI_DBG_TX("kni_sndmsg len %ld, flags 0x%08x, nb_iov %d\n",
+#ifdef HAVE_IOV_ITER_MSGHDR
+                  len, q->flags, (int)m->msg_iter.iov->iov_len);
+#else
                   len, q->flags, (int)m->msg_iovlen);
+#endif
 
 #ifdef RTE_KNI_VHOST_VNET_HDR_EN
        if (likely(q->flags & IFF_VNET_HDR)) {
@@ -322,18 +388,23 @@ kni_sock_sndmsg(struct kiocb *iocb, struct socket *sock,
        if (unlikely(len < ETH_HLEN + q->vnet_hdr_sz))
                return -EINVAL;
 
-       return kni_vhost_net_tx(q->kni, m->msg_iov, vnet_hdr_len, len);
+       return kni_vhost_net_tx(q->kni, m, vnet_hdr_len, len);
 }
 
-static int 
+static int
+#ifdef HAVE_KIOCB_MSG_PARAM
 kni_sock_rcvmsg(struct kiocb *iocb, struct socket *sock,
           struct msghdr *m, size_t len, int flags)
+#else
+kni_sock_rcvmsg(struct socket *sock,
+          struct msghdr *m, size_t len, int flags)
+#endif /* HAVE_KIOCB_MSG_PARAM */
 {
        int vnet_hdr_len = 0;
-       int pkt_len = 0; 
-       struct kni_vhost_queue *q = 
+       int pkt_len = 0;
+       struct kni_vhost_queue *q =
                container_of(sock->sk, struct kni_vhost_queue, sk);
-       static struct virtio_net_hdr 
+       static struct virtio_net_hdr
                __attribute__ ((unused)) vnet_hdr = {
                .flags = 0,
                .gso_type = VIRTIO_NET_HDR_GSO_NONE
@@ -350,31 +421,36 @@ kni_sock_rcvmsg(struct kiocb *iocb, struct socket *sock,
        }
 #endif
 
-       if (unlikely(0 == (pkt_len = kni_vhost_net_rx(q->kni, 
-               m->msg_iov, vnet_hdr_len, len))))
+       if (unlikely(0 == (pkt_len = kni_vhost_net_rx(q->kni,
+               m, vnet_hdr_len, len))))
                return 0;
 
 #ifdef RTE_KNI_VHOST_VNET_HDR_EN
        /* no need to copy hdr when no pkt received */
-       if (unlikely(memcpy_toiovecend(m->msg_iov, 
+#ifdef HAVE_IOV_ITER_MSGHDR
+       if (unlikely(copy_to_iter((void *)&vnet_hdr, vnet_hdr_len,
+               &m->msg_iter)))
+#else
+       if (unlikely(memcpy_toiovecend(m->msg_iov,
                (void *)&vnet_hdr, 0, vnet_hdr_len)))
+#endif /* HAVE_IOV_ITER_MSGHDR */
                return -EFAULT;
-#endif
-       KNI_DBG_RX("kni_rcvmsg expect_len %ld, flags 0x%08x, pkt_len %d\n", 
+#endif /* RTE_KNI_VHOST_VNET_HDR_EN */
+       KNI_DBG_RX("kni_rcvmsg expect_len %ld, flags 0x%08x, pkt_len %d\n",
                   (unsigned long)len, q->flags, pkt_len);
 
-       return (pkt_len + vnet_hdr_len); 
+       return pkt_len + vnet_hdr_len;
 }
 
 /* dummy tap like ioctl */
-static int 
+static int
 kni_sock_ioctl(struct socket *sock, unsigned int cmd,
              unsigned long arg)
 {
        void __user *argp = (void __user *)arg;
        struct ifreq __user *ifr = argp;
        unsigned int __user *up = argp;
-       struct kni_vhost_queue *q = 
+       struct kni_vhost_queue *q =
                container_of(sock->sk, struct kni_vhost_queue, sk);
        struct kni_dev *kni;
        unsigned int u;
@@ -423,7 +499,7 @@ kni_sock_ioctl(struct socket *sock, unsigned int cmd,
 #ifdef RTE_KNI_VHOST_VNET_HDR_EN
                u |= IFF_VNET_HDR;
 #endif
-               if (put_user(u, up))  
+               if (put_user(u, up))
                        return -EFAULT;
                return 0;
 
@@ -470,7 +546,7 @@ kni_sock_ioctl(struct socket *sock, unsigned int cmd,
        }
 }
 
-static int 
+static int
 kni_sock_compat_ioctl(struct socket *sock, unsigned int cmd,
                     unsigned long arg)
 {
@@ -487,10 +563,10 @@ do {                                                      \
 }while(0)                                               \
 
 
-static int 
+static int
 kni_sock_release(struct socket *sock)
 {
-       struct kni_vhost_queue *q = 
+       struct kni_vhost_queue *q =
                container_of(sock->sk, struct kni_vhost_queue, sk);
        struct kni_dev *kni;
 
@@ -511,13 +587,13 @@ kni_sock_release(struct socket *sock)
        sock->sk = NULL;
 
        sock_put(&q->sk);
-       
+
        KNI_DBG("dummy sock release done\n");
 
        return 0;
 }
 
-int 
+int
 kni_sock_getname (struct socket *sock,
                  struct sockaddr *addr,
                  int *sockaddr_len, int peer)
@@ -537,13 +613,13 @@ static const struct proto_ops kni_socket_ops = {
        .compat_ioctl = kni_sock_compat_ioctl,
 };
 
-static void 
+static void
 kni_sk_write_space(struct sock *sk)
 {
        wait_queue_head_t *wqueue;
 
-       if (!sock_writeable(sk) || 
-           !test_and_clear_bit(SOCK_ASYNC_NOSPACE, 
+       if (!sock_writeable(sk) ||
+           !test_and_clear_bit(SOCK_ASYNC_NOSPACE,
                                &sk->sk_socket->flags))
                return;
        wqueue = sk_sleep(sk);
@@ -552,10 +628,10 @@ kni_sk_write_space(struct sock *sk)
                        wqueue, POLLOUT | POLLWRNORM | POLLWRBAND);
 }
 
-static void 
+static void
 kni_sk_destruct(struct sock *sk)
 {
-       struct kni_vhost_queue *q = 
+       struct kni_vhost_queue *q =
                container_of(sk, struct kni_vhost_queue, sk);
 
        if (!q)
@@ -578,7 +654,7 @@ kni_sk_destruct(struct sock *sk)
        }
 }
 
-static int 
+static int
 kni_vhost_backend_init(struct kni_dev *kni)
 {
        struct kni_vhost_queue *q;
@@ -598,21 +674,19 @@ kni_vhost_backend_init(struct kni_dev *kni)
        if (err)
                goto free_sk;
 
-       sockfd = sock_map_fd(q->sock, 0);
+       sockfd = kni_sock_map_fd(q->sock);
        if (sockfd < 0) {
                err = sockfd;
                goto free_sock;
        }
 
        /* cache init */
-       q->cache = (struct sk_buff*)
-               kzalloc(RTE_KNI_VHOST_MAX_CACHE_SIZE * sizeof(struct sk_buff), 
-                       GFP_KERNEL);
+       q->cache = kzalloc(RTE_KNI_VHOST_MAX_CACHE_SIZE * sizeof(struct sk_buff),
+                          GFP_KERNEL);
        if (!q->cache)
                goto free_fd;
 
-       fifo = (struct rte_kni_fifo*)
-               kzalloc(RTE_KNI_VHOST_MAX_CACHE_SIZE * sizeof(void *)
+       fifo = kzalloc(RTE_KNI_VHOST_MAX_CACHE_SIZE * sizeof(void *)
                        + sizeof(struct rte_kni_fifo), GFP_KERNEL);
        if (!fifo)
                goto free_cache;
@@ -624,7 +698,7 @@ kni_vhost_backend_init(struct kni_dev *kni)
                kni_fifo_put(fifo, (void**)&elem, 1);
        }
        q->fifo = fifo;
-       
+
        /* store sockfd in vhost_queue */
        q->sockfd = sockfd;
 
@@ -642,19 +716,26 @@ kni_vhost_backend_init(struct kni_dev *kni)
 #ifdef RTE_KNI_VHOST_VNET_HDR_EN
        q->flags |= IFF_VNET_HDR;
 #endif
-       
+
        /* bind kni_dev with vhost_queue */
        q->kni = kni;
        kni->vhost_queue = q;
-       
+
        wmb();
 
        kni->vq_status = BE_START;
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)
        KNI_DBG("backend init sockfd=%d, sock->wq=0x%16llx,"
-                 "sk->sk_wq=0x%16llx", 
-                 q->sockfd, (uint64_t)q->sock->wq, 
+                 "sk->sk_wq=0x%16llx",
+                 q->sockfd, (uint64_t)q->sock->wq,
                  (uint64_t)q->sk.sk_wq);
+#else
+       KNI_DBG("backend init sockfd=%d, sock->wait at 0x%16llx,"
+                 "sk->sk_sleep=0x%16llx",
+                 q->sockfd, (uint64_t)&q->sock->wait,
+                 (uint64_t)q->sk.sk_sleep);
+#endif
 
        return 0;
 
@@ -710,10 +791,10 @@ set_sock_en(struct device *dev, struct device_attribute *attr,
        unsigned long en;
        int err = 0;
 
-       if (0 != strict_strtoul(buf, 0, &en))
+       if (0 != kstrtoul(buf, 0, &en))
                return -EINVAL;
 
-       if (en) 
+       if (en)
                err = kni_vhost_backend_init(kni);
 
        return err ? err : count;
@@ -731,11 +812,11 @@ static const struct attribute_group dev_attr_grp = {
        .attrs = dev_attrs,
 };
 
-int 
+int
 kni_vhost_backend_release(struct kni_dev *kni)
 {
-       struct kni_vhost_queue *q = kni->vhost_queue; 
-       
+       struct kni_vhost_queue *q = kni->vhost_queue;
+
        if (q == NULL)
                return 0;
 
@@ -747,7 +828,7 @@ kni_vhost_backend_release(struct kni_dev *kni)
        return 0;
 }
 
-int 
+int
 kni_vhost_init(struct kni_dev *kni)
 {
        struct net_device *dev = kni->net_dev;
@@ -761,4 +842,3 @@ kni_vhost_init(struct kni_dev *kni)
 
        return 0;
 }
-