/*
 * 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) 2007, 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.
 *
 * lnet/selftest/brw_test.c
 *
 * Author: Isaac Huang <isaac@clusterfs.com>
 */

#include "selftest.h"

static int brw_srv_workitems = SFW_TEST_WI_MAX;
module_param(brw_srv_workitems, int, 0644);
MODULE_PARM_DESC(brw_srv_workitems, "# BRW server workitems");

static int brw_inject_errors;
module_param(brw_inject_errors, int, 0644);
MODULE_PARM_DESC(brw_inject_errors, "# data errors to inject randomly, zero by default");

static void
brw_client_fini(sfw_test_instance_t *tsi)
{
	srpc_bulk_t     *bulk;
	sfw_test_unit_t *tsu;

	LASSERT(tsi->tsi_is_client);

	list_for_each_entry(tsu, &tsi->tsi_units, tsu_list) {
		bulk = tsu->tsu_private;
		if (bulk == NULL)
			continue;

		srpc_free_bulk(bulk);
		tsu->tsu_private = NULL;
	}
}

static int
brw_client_init(sfw_test_instance_t *tsi)
{
	sfw_session_t	 *sn = tsi->tsi_batch->bat_session;
	int		  flags;
	int		  npg;
	int		  len;
	int		  opc;
	srpc_bulk_t	 *bulk;
	sfw_test_unit_t	 *tsu;

	LASSERT(sn != NULL);
	LASSERT(tsi->tsi_is_client);

	if ((sn->sn_features & LST_FEAT_BULK_LEN) == 0) {
		test_bulk_req_t  *breq = &tsi->tsi_u.bulk_v0;

		opc   = breq->blk_opc;
		flags = breq->blk_flags;
		npg   = breq->blk_npg;
		/* NB: this is not going to work for variable page size,
		 * but we have to keep it for compatibility */
		len   = npg * PAGE_CACHE_SIZE;

	} else {
		test_bulk_req_v1_t  *breq = &tsi->tsi_u.bulk_v1;

		/* I should never get this step if it's unknown feature
		 * because make_session will reject unknown feature */
		LASSERT((sn->sn_features & ~LST_FEATS_MASK) == 0);

		opc   = breq->blk_opc;
		flags = breq->blk_flags;
		len   = breq->blk_len;
		npg   = (len + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
	}

	if (npg > LNET_MAX_IOV || npg <= 0)
		return -EINVAL;

	if (opc != LST_BRW_READ && opc != LST_BRW_WRITE)
		return -EINVAL;

	if (flags != LST_BRW_CHECK_NONE &&
	    flags != LST_BRW_CHECK_FULL && flags != LST_BRW_CHECK_SIMPLE)
		return -EINVAL;

	list_for_each_entry(tsu, &tsi->tsi_units, tsu_list) {
		bulk = srpc_alloc_bulk(lnet_cpt_of_nid(tsu->tsu_dest.nid),
				       npg, len, opc == LST_BRW_READ);
		if (bulk == NULL) {
			brw_client_fini(tsi);
			return -ENOMEM;
		}

		tsu->tsu_private = bulk;
	}

	return 0;
}

#define BRW_POISON      0xbeefbeefbeefbeefULL
#define BRW_MAGIC       0xeeb0eeb1eeb2eeb3ULL
#define BRW_MSIZE       sizeof(__u64)

static int
brw_inject_one_error(void)
{
	struct timeval tv;

	if (brw_inject_errors <= 0)
		return 0;

	do_gettimeofday(&tv);

	if ((tv.tv_usec & 1) == 0)
		return 0;

	return brw_inject_errors--;
}

static void
brw_fill_page(struct page *pg, int pattern, __u64 magic)
{
	char *addr = page_address(pg);
	int   i;

	LASSERT(addr != NULL);

	if (pattern == LST_BRW_CHECK_NONE)
		return;

	if (magic == BRW_MAGIC)
		magic += brw_inject_one_error();

	if (pattern == LST_BRW_CHECK_SIMPLE) {
		memcpy(addr, &magic, BRW_MSIZE);
		addr += PAGE_CACHE_SIZE - BRW_MSIZE;
		memcpy(addr, &magic, BRW_MSIZE);
		return;
	}

	if (pattern == LST_BRW_CHECK_FULL) {
		for (i = 0; i < PAGE_CACHE_SIZE / BRW_MSIZE; i++)
			memcpy(addr + i * BRW_MSIZE, &magic, BRW_MSIZE);
		return;
	}

	LBUG();
}

static int
brw_check_page(struct page *pg, int pattern, __u64 magic)
{
	char  *addr = page_address(pg);
	__u64  data = 0; /* make compiler happy */
	int    i;

	LASSERT(addr != NULL);

	if (pattern == LST_BRW_CHECK_NONE)
		return 0;

	if (pattern == LST_BRW_CHECK_SIMPLE) {
		data = *((__u64 *) addr);
		if (data != magic)
			goto bad_data;

		addr += PAGE_CACHE_SIZE - BRW_MSIZE;
		data = *((__u64 *) addr);
		if (data != magic)
			goto bad_data;

		return 0;
	}

	if (pattern == LST_BRW_CHECK_FULL) {
		for (i = 0; i < PAGE_CACHE_SIZE / BRW_MSIZE; i++) {
			data = *(((__u64 *) addr) + i);
			if (data != magic)
				goto bad_data;
		}

		return 0;
	}

	LBUG();

bad_data:
	CERROR("Bad data in page %p: %#llx, %#llx expected\n",
		pg, data, magic);
	return 1;
}

static void
brw_fill_bulk(srpc_bulk_t *bk, int pattern, __u64 magic)
{
	int	 i;
	struct page *pg;

	for (i = 0; i < bk->bk_niov; i++) {
		pg = bk->bk_iovs[i].kiov_page;
		brw_fill_page(pg, pattern, magic);
	}
}

static int
brw_check_bulk(srpc_bulk_t *bk, int pattern, __u64 magic)
{
	int	 i;
	struct page *pg;

	for (i = 0; i < bk->bk_niov; i++) {
		pg = bk->bk_iovs[i].kiov_page;
		if (brw_check_page(pg, pattern, magic) != 0) {
			CERROR("Bulk page %p (%d/%d) is corrupted!\n",
				pg, i, bk->bk_niov);
			return 1;
		}
	}

	return 0;
}

static int
brw_client_prep_rpc(sfw_test_unit_t *tsu,
		     lnet_process_id_t dest, srpc_client_rpc_t **rpcpp)
{
	srpc_bulk_t	 *bulk = tsu->tsu_private;
	sfw_test_instance_t *tsi = tsu->tsu_instance;
	sfw_session_t	    *sn = tsi->tsi_batch->bat_session;
	srpc_client_rpc_t   *rpc;
	srpc_brw_reqst_t    *req;
	int		     flags;
	int		     npg;
	int		     len;
	int		     opc;
	int		     rc;

	LASSERT(sn != NULL);
	LASSERT(bulk != NULL);

	if ((sn->sn_features & LST_FEAT_BULK_LEN) == 0) {
		test_bulk_req_t *breq = &tsi->tsi_u.bulk_v0;

		opc   = breq->blk_opc;
		flags = breq->blk_flags;
		npg   = breq->blk_npg;
		len   = npg * PAGE_CACHE_SIZE;

	} else {
		test_bulk_req_v1_t  *breq = &tsi->tsi_u.bulk_v1;

		/* I should never get this step if it's unknown feature
		 * because make_session will reject unknown feature */
		LASSERT((sn->sn_features & ~LST_FEATS_MASK) == 0);

		opc   = breq->blk_opc;
		flags = breq->blk_flags;
		len   = breq->blk_len;
		npg   = (len + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
	}

	rc = sfw_create_test_rpc(tsu, dest, sn->sn_features, npg, len, &rpc);
	if (rc != 0)
		return rc;

	memcpy(&rpc->crpc_bulk, bulk, offsetof(srpc_bulk_t, bk_iovs[npg]));
	if (opc == LST_BRW_WRITE)
		brw_fill_bulk(&rpc->crpc_bulk, flags, BRW_MAGIC);
	else
		brw_fill_bulk(&rpc->crpc_bulk, flags, BRW_POISON);

	req = &rpc->crpc_reqstmsg.msg_body.brw_reqst;
	req->brw_flags = flags;
	req->brw_rw    = opc;
	req->brw_len   = len;

	*rpcpp = rpc;
	return 0;
}

static void
brw_client_done_rpc(sfw_test_unit_t *tsu, srpc_client_rpc_t *rpc)
{
	__u64		magic = BRW_MAGIC;
	sfw_test_instance_t *tsi = tsu->tsu_instance;
	sfw_session_t       *sn = tsi->tsi_batch->bat_session;
	srpc_msg_t	  *msg = &rpc->crpc_replymsg;
	srpc_brw_reply_t    *reply = &msg->msg_body.brw_reply;
	srpc_brw_reqst_t    *reqst = &rpc->crpc_reqstmsg.msg_body.brw_reqst;

	LASSERT(sn != NULL);

	if (rpc->crpc_status != 0) {
		CERROR("BRW RPC to %s failed with %d\n",
			libcfs_id2str(rpc->crpc_dest), rpc->crpc_status);
		if (!tsi->tsi_stopping) /* rpc could have been aborted */
			atomic_inc(&sn->sn_brw_errors);
		goto out;
	}

	if (msg->msg_magic != SRPC_MSG_MAGIC) {
		__swab64s(&magic);
		__swab32s(&reply->brw_status);
	}

	CDEBUG(reply->brw_status ? D_WARNING : D_NET,
		"BRW RPC to %s finished with brw_status: %d\n",
		libcfs_id2str(rpc->crpc_dest), reply->brw_status);

	if (reply->brw_status != 0) {
		atomic_inc(&sn->sn_brw_errors);
		rpc->crpc_status = -(int)reply->brw_status;
		goto out;
	}

	if (reqst->brw_rw == LST_BRW_WRITE)
		goto out;

	if (brw_check_bulk(&rpc->crpc_bulk, reqst->brw_flags, magic) != 0) {
		CERROR("Bulk data from %s is corrupted!\n",
			libcfs_id2str(rpc->crpc_dest));
		atomic_inc(&sn->sn_brw_errors);
		rpc->crpc_status = -EBADMSG;
	}

out:
	return;
}

static void
brw_server_rpc_done(srpc_server_rpc_t *rpc)
{
	srpc_bulk_t *blk = rpc->srpc_bulk;

	if (blk == NULL)
		return;

	if (rpc->srpc_status != 0)
		CERROR("Bulk transfer %s %s has failed: %d\n",
			blk->bk_sink ? "from" : "to",
			libcfs_id2str(rpc->srpc_peer), rpc->srpc_status);
	else
		CDEBUG(D_NET, "Transferred %d pages bulk data %s %s\n",
			blk->bk_niov, blk->bk_sink ? "from" : "to",
			libcfs_id2str(rpc->srpc_peer));

	sfw_free_pages(rpc);
}

static int
brw_bulk_ready(srpc_server_rpc_t *rpc, int status)
{
	__u64	     magic = BRW_MAGIC;
	srpc_brw_reply_t *reply = &rpc->srpc_replymsg.msg_body.brw_reply;
	srpc_brw_reqst_t *reqst;
	srpc_msg_t       *reqstmsg;

	LASSERT(rpc->srpc_bulk != NULL);
	LASSERT(rpc->srpc_reqstbuf != NULL);

	reqstmsg = &rpc->srpc_reqstbuf->buf_msg;
	reqst = &reqstmsg->msg_body.brw_reqst;

	if (status != 0) {
		CERROR("BRW bulk %s failed for RPC from %s: %d\n",
			reqst->brw_rw == LST_BRW_READ ? "READ" : "WRITE",
			libcfs_id2str(rpc->srpc_peer), status);
		return -EIO;
	}

	if (reqst->brw_rw == LST_BRW_READ)
		return 0;

	if (reqstmsg->msg_magic != SRPC_MSG_MAGIC)
		__swab64s(&magic);

	if (brw_check_bulk(rpc->srpc_bulk, reqst->brw_flags, magic) != 0) {
		CERROR("Bulk data from %s is corrupted!\n",
			libcfs_id2str(rpc->srpc_peer));
		reply->brw_status = EBADMSG;
	}

	return 0;
}

static int
brw_server_handle(struct srpc_server_rpc *rpc)
{
	struct srpc_service	*sv = rpc->srpc_scd->scd_svc;
	srpc_msg_t       *replymsg = &rpc->srpc_replymsg;
	srpc_msg_t       *reqstmsg = &rpc->srpc_reqstbuf->buf_msg;
	srpc_brw_reply_t *reply = &replymsg->msg_body.brw_reply;
	srpc_brw_reqst_t *reqst = &reqstmsg->msg_body.brw_reqst;
	int		  npg;
	int	       rc;

	LASSERT(sv->sv_id == SRPC_SERVICE_BRW);

	if (reqstmsg->msg_magic != SRPC_MSG_MAGIC) {
		LASSERT(reqstmsg->msg_magic == __swab32(SRPC_MSG_MAGIC));

		__swab32s(&reqst->brw_rw);
		__swab32s(&reqst->brw_len);
		__swab32s(&reqst->brw_flags);
		__swab64s(&reqst->brw_rpyid);
		__swab64s(&reqst->brw_bulkid);
	}
	LASSERT(reqstmsg->msg_type == (__u32)srpc_service2request(sv->sv_id));

	reply->brw_status = 0;
	rpc->srpc_done = brw_server_rpc_done;

	if ((reqst->brw_rw != LST_BRW_READ && reqst->brw_rw != LST_BRW_WRITE) ||
	    (reqst->brw_flags != LST_BRW_CHECK_NONE &&
	     reqst->brw_flags != LST_BRW_CHECK_FULL &&
	     reqst->brw_flags != LST_BRW_CHECK_SIMPLE)) {
		reply->brw_status = EINVAL;
		return 0;
	}

	if ((reqstmsg->msg_ses_feats & ~LST_FEATS_MASK) != 0) {
		replymsg->msg_ses_feats = LST_FEATS_MASK;
		reply->brw_status = EPROTO;
		return 0;
	}

	if ((reqstmsg->msg_ses_feats & LST_FEAT_BULK_LEN) == 0) {
		/* compat with old version */
		if ((reqst->brw_len & ~CFS_PAGE_MASK) != 0) {
			reply->brw_status = EINVAL;
			return 0;
		}
		npg = reqst->brw_len >> PAGE_CACHE_SHIFT;

	} else {
		npg = (reqst->brw_len + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
	}

	replymsg->msg_ses_feats = reqstmsg->msg_ses_feats;

	if (reqst->brw_len == 0 || npg > LNET_MAX_IOV) {
		reply->brw_status = EINVAL;
		return 0;
	}

	rc = sfw_alloc_pages(rpc, rpc->srpc_scd->scd_cpt, npg,
			     reqst->brw_len,
			     reqst->brw_rw == LST_BRW_WRITE);
	if (rc != 0)
		return rc;

	if (reqst->brw_rw == LST_BRW_READ)
		brw_fill_bulk(rpc->srpc_bulk, reqst->brw_flags, BRW_MAGIC);
	else
		brw_fill_bulk(rpc->srpc_bulk, reqst->brw_flags, BRW_POISON);

	return 0;
}

sfw_test_client_ops_t brw_test_client;
void brw_init_test_client(void)
{
	brw_test_client.tso_init       = brw_client_init;
	brw_test_client.tso_fini       = brw_client_fini;
	brw_test_client.tso_prep_rpc   = brw_client_prep_rpc;
	brw_test_client.tso_done_rpc   = brw_client_done_rpc;
};

srpc_service_t brw_test_service;
void brw_init_test_service(void)
{

	brw_test_service.sv_id	 = SRPC_SERVICE_BRW;
	brw_test_service.sv_name       = "brw_test";
	brw_test_service.sv_handler    = brw_server_handle;
	brw_test_service.sv_bulk_ready = brw_bulk_ready;
	brw_test_service.sv_wi_total   = brw_srv_workitems;
}
