/*
 * GPL HEADER START
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 only,
 * 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 version 2 for more details (a copy is included
 * in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU General Public License
 * version 2 along with this program; If not, see
 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 *
 * GPL HEADER END
 */
/*
 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
 * Use is subject to license terms.
 *
 * Copyright (c) 2011, 2012, Intel Corporation.
 */
/*
 * This file is part of Lustre, http://www.lustre.org/
 * Lustre is a trademark of Sun Microsystems, Inc.
 */

#include "socklnd.h"

int
ksocknal_lib_get_conn_addrs (ksock_conn_t *conn)
{
	int rc = libcfs_sock_getaddr(conn->ksnc_sock, 1,
				     &conn->ksnc_ipaddr,
				     &conn->ksnc_port);

	/* Didn't need the {get,put}connsock dance to deref ksnc_sock... */
	LASSERT (!conn->ksnc_closing);

	if (rc != 0) {
		CERROR ("Error %d getting sock peer IP\n", rc);
		return rc;
	}

	rc = libcfs_sock_getaddr(conn->ksnc_sock, 0,
				 &conn->ksnc_myipaddr, NULL);
	if (rc != 0) {
		CERROR ("Error %d getting sock local IP\n", rc);
		return rc;
	}

	return 0;
}

int
ksocknal_lib_zc_capable(ksock_conn_t *conn)
{
	int  caps = conn->ksnc_sock->sk->sk_route_caps;

	if (conn->ksnc_proto == &ksocknal_protocol_v1x)
		return 0;

	/* ZC if the socket supports scatter/gather and doesn't need software
	 * checksums */
	return ((caps & NETIF_F_SG) != 0 && (caps & NETIF_F_ALL_CSUM) != 0);
}

int
ksocknal_lib_send_iov (ksock_conn_t *conn, ksock_tx_t *tx)
{
	struct socket *sock = conn->ksnc_sock;
	int	    nob;
	int	    rc;

	if (*ksocknal_tunables.ksnd_enable_csum	&& /* checksum enabled */
	    conn->ksnc_proto == &ksocknal_protocol_v2x && /* V2.x connection  */
	    tx->tx_nob == tx->tx_resid		 && /* frist sending    */
	    tx->tx_msg.ksm_csum == 0)		     /* not checksummed  */
		ksocknal_lib_csum_tx(tx);

	/* NB we can't trust socket ops to either consume our iovs
	 * or leave them alone. */

	{
#if SOCKNAL_SINGLE_FRAG_TX
		struct iovec    scratch;
		struct iovec   *scratchiov = &scratch;
		unsigned int    niov = 1;
#else
		struct iovec   *scratchiov = conn->ksnc_scheduler->kss_scratch_iov;
		unsigned int    niov = tx->tx_niov;
#endif
		struct msghdr msg = {.msg_flags = MSG_DONTWAIT};
		int  i;

		for (nob = i = 0; i < niov; i++) {
			scratchiov[i] = tx->tx_iov[i];
			nob += scratchiov[i].iov_len;
		}

		if (!list_empty(&conn->ksnc_tx_queue) ||
		    nob < tx->tx_resid)
			msg.msg_flags |= MSG_MORE;

		rc = kernel_sendmsg(sock, &msg, (struct kvec *)scratchiov, niov, nob);
	}
	return rc;
}

int
ksocknal_lib_send_kiov (ksock_conn_t *conn, ksock_tx_t *tx)
{
	struct socket *sock = conn->ksnc_sock;
	lnet_kiov_t   *kiov = tx->tx_kiov;
	int	    rc;
	int	    nob;

	/* Not NOOP message */
	LASSERT (tx->tx_lnetmsg != NULL);

	/* NB we can't trust socket ops to either consume our iovs
	 * or leave them alone. */
	if (tx->tx_msg.ksm_zc_cookies[0] != 0) {
		/* Zero copy is enabled */
		struct sock   *sk = sock->sk;
		struct page   *page = kiov->kiov_page;
		int	    offset = kiov->kiov_offset;
		int	    fragsize = kiov->kiov_len;
		int	    msgflg = MSG_DONTWAIT;

		CDEBUG(D_NET, "page %p + offset %x for %d\n",
			       page, offset, kiov->kiov_len);

		if (!list_empty(&conn->ksnc_tx_queue) ||
		    fragsize < tx->tx_resid)
			msgflg |= MSG_MORE;

		if (sk->sk_prot->sendpage != NULL) {
			rc = sk->sk_prot->sendpage(sk, page,
						   offset, fragsize, msgflg);
		} else {
			rc = cfs_tcp_sendpage(sk, page, offset, fragsize,
					      msgflg);
		}
	} else {
#if SOCKNAL_SINGLE_FRAG_TX || !SOCKNAL_RISK_KMAP_DEADLOCK
		struct iovec  scratch;
		struct iovec *scratchiov = &scratch;
		unsigned int  niov = 1;
#else
#ifdef CONFIG_HIGHMEM
#warning "XXX risk of kmap deadlock on multiple frags..."
#endif
		struct iovec *scratchiov = conn->ksnc_scheduler->kss_scratch_iov;
		unsigned int  niov = tx->tx_nkiov;
#endif
		struct msghdr msg = {.msg_flags = MSG_DONTWAIT};
		int	   i;

		for (nob = i = 0; i < niov; i++) {
			scratchiov[i].iov_base = kmap(kiov[i].kiov_page) +
						 kiov[i].kiov_offset;
			nob += scratchiov[i].iov_len = kiov[i].kiov_len;
		}

		if (!list_empty(&conn->ksnc_tx_queue) ||
		    nob < tx->tx_resid)
			msg.msg_flags |= MSG_MORE;

		rc = kernel_sendmsg(sock, &msg, (struct kvec *)scratchiov, niov, nob);

		for (i = 0; i < niov; i++)
			kunmap(kiov[i].kiov_page);
	}
	return rc;
}

void
ksocknal_lib_eager_ack (ksock_conn_t *conn)
{
	int	    opt = 1;
	struct socket *sock = conn->ksnc_sock;

	/* Remind the socket to ACK eagerly.  If I don't, the socket might
	 * think I'm about to send something it could piggy-back the ACK
	 * on, introducing delay in completing zero-copy sends in my
	 * peer. */

	kernel_setsockopt(sock, SOL_TCP, TCP_QUICKACK,
			       (char *)&opt, sizeof (opt));
}

int
ksocknal_lib_recv_iov (ksock_conn_t *conn)
{
#if SOCKNAL_SINGLE_FRAG_RX
	struct iovec  scratch;
	struct iovec *scratchiov = &scratch;
	unsigned int  niov = 1;
#else
	struct iovec *scratchiov = conn->ksnc_scheduler->kss_scratch_iov;
	unsigned int  niov = conn->ksnc_rx_niov;
#endif
	struct iovec *iov = conn->ksnc_rx_iov;
	struct msghdr msg = {
		.msg_flags      = 0
	};
	int	  nob;
	int	  i;
	int	  rc;
	int	  fragnob;
	int	  sum;
	__u32	saved_csum;

	/* NB we can't trust socket ops to either consume our iovs
	 * or leave them alone. */
	LASSERT (niov > 0);

	for (nob = i = 0; i < niov; i++) {
		scratchiov[i] = iov[i];
		nob += scratchiov[i].iov_len;
	}
	LASSERT (nob <= conn->ksnc_rx_nob_wanted);

	rc = kernel_recvmsg(conn->ksnc_sock, &msg,
		(struct kvec *)scratchiov, niov, nob, MSG_DONTWAIT);

	saved_csum = 0;
	if (conn->ksnc_proto == &ksocknal_protocol_v2x) {
		saved_csum = conn->ksnc_msg.ksm_csum;
		conn->ksnc_msg.ksm_csum = 0;
	}

	if (saved_csum != 0) {
		/* accumulate checksum */
		for (i = 0, sum = rc; sum > 0; i++, sum -= fragnob) {
			LASSERT (i < niov);

			fragnob = iov[i].iov_len;
			if (fragnob > sum)
				fragnob = sum;

			conn->ksnc_rx_csum = ksocknal_csum(conn->ksnc_rx_csum,
							   iov[i].iov_base, fragnob);
		}
		conn->ksnc_msg.ksm_csum = saved_csum;
	}

	return rc;
}

static void
ksocknal_lib_kiov_vunmap(void *addr)
{
	if (addr == NULL)
		return;

	vunmap(addr);
}

static void *
ksocknal_lib_kiov_vmap(lnet_kiov_t *kiov, int niov,
		       struct iovec *iov, struct page **pages)
{
	void	     *addr;
	int	       nob;
	int	       i;

	if (!*ksocknal_tunables.ksnd_zc_recv || pages == NULL)
		return NULL;

	LASSERT (niov <= LNET_MAX_IOV);

	if (niov < 2 ||
	    niov < *ksocknal_tunables.ksnd_zc_recv_min_nfrags)
		return NULL;

	for (nob = i = 0; i < niov; i++) {
		if ((kiov[i].kiov_offset != 0 && i > 0) ||
		    (kiov[i].kiov_offset + kiov[i].kiov_len != PAGE_CACHE_SIZE && i < niov - 1))
			return NULL;

		pages[i] = kiov[i].kiov_page;
		nob += kiov[i].kiov_len;
	}

	addr = vmap(pages, niov, VM_MAP, PAGE_KERNEL);
	if (addr == NULL)
		return NULL;

	iov->iov_base = addr + kiov[0].kiov_offset;
	iov->iov_len = nob;

	return addr;
}

int
ksocknal_lib_recv_kiov (ksock_conn_t *conn)
{
#if SOCKNAL_SINGLE_FRAG_RX || !SOCKNAL_RISK_KMAP_DEADLOCK
	struct iovec   scratch;
	struct iovec  *scratchiov = &scratch;
	struct page  **pages      = NULL;
	unsigned int   niov       = 1;
#else
#ifdef CONFIG_HIGHMEM
#warning "XXX risk of kmap deadlock on multiple frags..."
#endif
	struct iovec  *scratchiov = conn->ksnc_scheduler->kss_scratch_iov;
	struct page  **pages      = conn->ksnc_scheduler->kss_rx_scratch_pgs;
	unsigned int   niov       = conn->ksnc_rx_nkiov;
#endif
	lnet_kiov_t   *kiov = conn->ksnc_rx_kiov;
	struct msghdr msg = {
		.msg_flags      = 0
	};
	int	  nob;
	int	  i;
	int	  rc;
	void	*base;
	void	*addr;
	int	  sum;
	int	  fragnob;
	int n;

	/* NB we can't trust socket ops to either consume our iovs
	 * or leave them alone. */
	addr = ksocknal_lib_kiov_vmap(kiov, niov, scratchiov, pages);
	if (addr != NULL) {
		nob = scratchiov[0].iov_len;
		n = 1;

	} else {
		for (nob = i = 0; i < niov; i++) {
			nob += scratchiov[i].iov_len = kiov[i].kiov_len;
			scratchiov[i].iov_base = kmap(kiov[i].kiov_page) +
						 kiov[i].kiov_offset;
		}
		n = niov;
	}

	LASSERT (nob <= conn->ksnc_rx_nob_wanted);

	rc = kernel_recvmsg(conn->ksnc_sock, &msg,
			(struct kvec *)scratchiov, n, nob, MSG_DONTWAIT);

	if (conn->ksnc_msg.ksm_csum != 0) {
		for (i = 0, sum = rc; sum > 0; i++, sum -= fragnob) {
			LASSERT (i < niov);

			/* Dang! have to kmap again because I have nowhere to stash the
			 * mapped address.  But by doing it while the page is still
			 * mapped, the kernel just bumps the map count and returns me
			 * the address it stashed. */
			base = kmap(kiov[i].kiov_page) + kiov[i].kiov_offset;
			fragnob = kiov[i].kiov_len;
			if (fragnob > sum)
				fragnob = sum;

			conn->ksnc_rx_csum = ksocknal_csum(conn->ksnc_rx_csum,
							   base, fragnob);

			kunmap(kiov[i].kiov_page);
		}
	}

	if (addr != NULL) {
		ksocknal_lib_kiov_vunmap(addr);
	} else {
		for (i = 0; i < niov; i++)
			kunmap(kiov[i].kiov_page);
	}

	return rc;
}

void
ksocknal_lib_csum_tx(ksock_tx_t *tx)
{
	int	  i;
	__u32	csum;
	void	*base;

	LASSERT(tx->tx_iov[0].iov_base == (void *)&tx->tx_msg);
	LASSERT(tx->tx_conn != NULL);
	LASSERT(tx->tx_conn->ksnc_proto == &ksocknal_protocol_v2x);

	tx->tx_msg.ksm_csum = 0;

	csum = ksocknal_csum(~0, (void *)tx->tx_iov[0].iov_base,
			     tx->tx_iov[0].iov_len);

	if (tx->tx_kiov != NULL) {
		for (i = 0; i < tx->tx_nkiov; i++) {
			base = kmap(tx->tx_kiov[i].kiov_page) +
			       tx->tx_kiov[i].kiov_offset;

			csum = ksocknal_csum(csum, base, tx->tx_kiov[i].kiov_len);

			kunmap(tx->tx_kiov[i].kiov_page);
		}
	} else {
		for (i = 1; i < tx->tx_niov; i++)
			csum = ksocknal_csum(csum, tx->tx_iov[i].iov_base,
					     tx->tx_iov[i].iov_len);
	}

	if (*ksocknal_tunables.ksnd_inject_csum_error) {
		csum++;
		*ksocknal_tunables.ksnd_inject_csum_error = 0;
	}

	tx->tx_msg.ksm_csum = csum;
}

int
ksocknal_lib_get_conn_tunables (ksock_conn_t *conn, int *txmem, int *rxmem, int *nagle)
{
	struct socket *sock = conn->ksnc_sock;
	int	    len;
	int	    rc;

	rc = ksocknal_connsock_addref(conn);
	if (rc != 0) {
		LASSERT (conn->ksnc_closing);
		*txmem = *rxmem = *nagle = 0;
		return -ESHUTDOWN;
	}

	rc = libcfs_sock_getbuf(sock, txmem, rxmem);
	if (rc == 0) {
		len = sizeof(*nagle);
		rc = kernel_getsockopt(sock, SOL_TCP, TCP_NODELAY,
					   (char *)nagle, &len);
	}

	ksocknal_connsock_decref(conn);

	if (rc == 0)
		*nagle = !*nagle;
	else
		*txmem = *rxmem = *nagle = 0;

	return rc;
}

int
ksocknal_lib_setup_sock (struct socket *sock)
{
	int	     rc;
	int	     option;
	int	     keep_idle;
	int	     keep_intvl;
	int	     keep_count;
	int	     do_keepalive;
	struct linger   linger;

	sock->sk->sk_allocation = GFP_NOFS;

	/* Ensure this socket aborts active sends immediately when we close
	 * it. */

	linger.l_onoff = 0;
	linger.l_linger = 0;

	rc = kernel_setsockopt(sock, SOL_SOCKET, SO_LINGER,
			      (char *)&linger, sizeof (linger));
	if (rc != 0) {
		CERROR ("Can't set SO_LINGER: %d\n", rc);
		return rc;
	}

	option = -1;
	rc = kernel_setsockopt(sock, SOL_TCP, TCP_LINGER2,
				    (char *)&option, sizeof (option));
	if (rc != 0) {
		CERROR ("Can't set SO_LINGER2: %d\n", rc);
		return rc;
	}

	if (!*ksocknal_tunables.ksnd_nagle) {
		option = 1;

		rc = kernel_setsockopt(sock, SOL_TCP, TCP_NODELAY,
					    (char *)&option, sizeof (option));
		if (rc != 0) {
			CERROR ("Can't disable nagle: %d\n", rc);
			return rc;
		}
	}

	rc = libcfs_sock_setbuf(sock,
				*ksocknal_tunables.ksnd_tx_buffer_size,
				*ksocknal_tunables.ksnd_rx_buffer_size);
	if (rc != 0) {
		CERROR ("Can't set buffer tx %d, rx %d buffers: %d\n",
			*ksocknal_tunables.ksnd_tx_buffer_size,
			*ksocknal_tunables.ksnd_rx_buffer_size, rc);
		return rc;
	}

/* TCP_BACKOFF_* sockopt tunables unsupported in stock kernels */

	/* snapshot tunables */
	keep_idle  = *ksocknal_tunables.ksnd_keepalive_idle;
	keep_count = *ksocknal_tunables.ksnd_keepalive_count;
	keep_intvl = *ksocknal_tunables.ksnd_keepalive_intvl;

	do_keepalive = (keep_idle > 0 && keep_count > 0 && keep_intvl > 0);

	option = (do_keepalive ? 1 : 0);
	rc = kernel_setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
			      (char *)&option, sizeof (option));
	if (rc != 0) {
		CERROR ("Can't set SO_KEEPALIVE: %d\n", rc);
		return rc;
	}

	if (!do_keepalive)
		return 0;

	rc = kernel_setsockopt(sock, SOL_TCP, TCP_KEEPIDLE,
				    (char *)&keep_idle, sizeof (keep_idle));
	if (rc != 0) {
		CERROR ("Can't set TCP_KEEPIDLE: %d\n", rc);
		return rc;
	}

	rc = kernel_setsockopt(sock, SOL_TCP, TCP_KEEPINTVL,
				    (char *)&keep_intvl, sizeof (keep_intvl));
	if (rc != 0) {
		CERROR ("Can't set TCP_KEEPINTVL: %d\n", rc);
		return rc;
	}

	rc = kernel_setsockopt(sock, SOL_TCP, TCP_KEEPCNT,
				    (char *)&keep_count, sizeof (keep_count));
	if (rc != 0) {
		CERROR ("Can't set TCP_KEEPCNT: %d\n", rc);
		return rc;
	}

	return 0;
}

void
ksocknal_lib_push_conn (ksock_conn_t *conn)
{
	struct sock    *sk;
	struct tcp_sock *tp;
	int	     nonagle;
	int	     val = 1;
	int	     rc;

	rc = ksocknal_connsock_addref(conn);
	if (rc != 0)			    /* being shut down */
		return;

	sk = conn->ksnc_sock->sk;
	tp = tcp_sk(sk);

	lock_sock (sk);
	nonagle = tp->nonagle;
	tp->nonagle = 1;
	release_sock (sk);

	rc = kernel_setsockopt(conn->ksnc_sock, SOL_TCP, TCP_NODELAY,
				      (char *)&val, sizeof (val));
	LASSERT (rc == 0);

	lock_sock (sk);
	tp->nonagle = nonagle;
	release_sock (sk);

	ksocknal_connsock_decref(conn);
}

extern void ksocknal_read_callback (ksock_conn_t *conn);
extern void ksocknal_write_callback (ksock_conn_t *conn);
/*
 * socket call back in Linux
 */
static void
ksocknal_data_ready (struct sock *sk)
{
	ksock_conn_t  *conn;

	/* interleave correctly with closing sockets... */
	LASSERT(!in_irq());
	read_lock(&ksocknal_data.ksnd_global_lock);

	conn = sk->sk_user_data;
	if (conn == NULL) {	     /* raced with ksocknal_terminate_conn */
		LASSERT (sk->sk_data_ready != &ksocknal_data_ready);
		sk->sk_data_ready (sk);
	} else
		ksocknal_read_callback(conn);

	read_unlock(&ksocknal_data.ksnd_global_lock);
}

static void
ksocknal_write_space (struct sock *sk)
{
	ksock_conn_t  *conn;
	int	    wspace;
	int	    min_wpace;

	/* interleave correctly with closing sockets... */
	LASSERT(!in_irq());
	read_lock(&ksocknal_data.ksnd_global_lock);

	conn = sk->sk_user_data;
	wspace = SOCKNAL_WSPACE(sk);
	min_wpace = SOCKNAL_MIN_WSPACE(sk);

	CDEBUG(D_NET, "sk %p wspace %d low water %d conn %p%s%s%s\n",
	       sk, wspace, min_wpace, conn,
	       (conn == NULL) ? "" : (conn->ksnc_tx_ready ?
				      " ready" : " blocked"),
	       (conn == NULL) ? "" : (conn->ksnc_tx_scheduled ?
				      " scheduled" : " idle"),
	       (conn == NULL) ? "" : (list_empty (&conn->ksnc_tx_queue) ?
				      " empty" : " queued"));

	if (conn == NULL) {	     /* raced with ksocknal_terminate_conn */
		LASSERT (sk->sk_write_space != &ksocknal_write_space);
		sk->sk_write_space (sk);

		read_unlock(&ksocknal_data.ksnd_global_lock);
		return;
	}

	if (wspace >= min_wpace) {	      /* got enough space */
		ksocknal_write_callback(conn);

		/* Clear SOCK_NOSPACE _after_ ksocknal_write_callback so the
		 * ENOMEM check in ksocknal_transmit is race-free (think about
		 * it). */

		clear_bit (SOCK_NOSPACE, &sk->sk_socket->flags);
	}

	read_unlock(&ksocknal_data.ksnd_global_lock);
}

void
ksocknal_lib_save_callback(struct socket *sock, ksock_conn_t *conn)
{
	conn->ksnc_saved_data_ready = sock->sk->sk_data_ready;
	conn->ksnc_saved_write_space = sock->sk->sk_write_space;
}

void
ksocknal_lib_set_callback(struct socket *sock,  ksock_conn_t *conn)
{
	sock->sk->sk_user_data = conn;
	sock->sk->sk_data_ready = ksocknal_data_ready;
	sock->sk->sk_write_space = ksocknal_write_space;
	return;
}

void
ksocknal_lib_reset_callback(struct socket *sock, ksock_conn_t *conn)
{
	/* Remove conn's network callbacks.
	 * NB I _have_ to restore the callback, rather than storing a noop,
	 * since the socket could survive past this module being unloaded!! */
	sock->sk->sk_data_ready = conn->ksnc_saved_data_ready;
	sock->sk->sk_write_space = conn->ksnc_saved_write_space;

	/* A callback could be in progress already; they hold a read lock
	 * on ksnd_global_lock (to serialise with me) and NOOP if
	 * sk_user_data is NULL. */
	sock->sk->sk_user_data = NULL;

	return ;
}

int
ksocknal_lib_memory_pressure(ksock_conn_t *conn)
{
	int	    rc = 0;
	ksock_sched_t *sched;

	sched = conn->ksnc_scheduler;
	spin_lock_bh(&sched->kss_lock);

	if (!SOCK_TEST_NOSPACE(conn->ksnc_sock) &&
	    !conn->ksnc_tx_ready) {
		/* SOCK_NOSPACE is set when the socket fills
		 * and cleared in the write_space callback
		 * (which also sets ksnc_tx_ready).  If
		 * SOCK_NOSPACE and ksnc_tx_ready are BOTH
		 * zero, I didn't fill the socket and
		 * write_space won't reschedule me, so I
		 * return -ENOMEM to get my caller to retry
		 * after a timeout */
		rc = -ENOMEM;
	}

	spin_unlock_bh(&sched->kss_lock);

	return rc;
}
