Whamcloud - gitweb
LU-13004 ptlrpc: Allow BULK_BUF_KIOV to accept a kvec
[fs/lustre-release.git] / lnet / selftest / brw_test.c
index e70ba12..55c9486 100644 (file)
  *
  * 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.
+ * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * GPL HEADER END
  */
@@ -27,7 +23,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, Intel Corporation.
+ * Copyright (c) 2012, 2017, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
 #include "selftest.h"
 
 static int brw_srv_workitems = SFW_TEST_WI_MAX;
-CFS_MODULE_PARM(brw_srv_workitems, "i", int, 0644, "# BRW server workitems");
+module_param(brw_srv_workitems, int, 0644);
+MODULE_PARM_DESC(brw_srv_workitems, "# BRW server workitems");
 
 static int brw_inject_errors;
-CFS_MODULE_PARM(brw_inject_errors, "i", int, 0644,
-               "# data errors to inject randomly, zero by default");
+module_param(brw_inject_errors, int, 0644);
+MODULE_PARM_DESC(brw_inject_errors, "# data errors to inject randomly, zero by default");
+
+#define BRW_POISON     0xbeefbeefbeefbeefULL
+#define BRW_MAGIC      0xeeb0eeb1eeb2eeb3ULL
+#define BRW_MSIZE      sizeof(__u64)
 
 static void
-brw_client_fini (sfw_test_instance_t *tsi)
+brw_client_fini(struct sfw_test_instance *tsi)
 {
-       srpc_bulk_t     *bulk;
-       sfw_test_unit_t *tsu;
+       struct srpc_bulk *bulk;
+       struct sfw_test_unit *tsu;
 
        LASSERT(tsi->tsi_is_client);
 
@@ -66,31 +67,33 @@ brw_client_fini (sfw_test_instance_t *tsi)
 }
 
 static int
-brw_client_init (sfw_test_instance_t *tsi)
+brw_client_init(struct sfw_test_instance *tsi)
 {
-       sfw_session_t    *sn = tsi->tsi_batch->bat_session;
+       struct sfw_session *sn = tsi->tsi_batch->bat_session;
        int               flags;
+       int               off;
        int               npg;
        int               len;
        int               opc;
-       srpc_bulk_t      *bulk;
-       sfw_test_unit_t  *tsu;
+       struct srpc_bulk *bulk;
+       struct sfw_test_unit *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;
+               struct test_bulk_req *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;
+               len   = npg * PAGE_SIZE;
+               off   = 0;
 
        } else {
-               test_bulk_req_v1_t  *breq = &tsi->tsi_u.bulk_v1;
+               struct test_bulk_req_v1 *breq = &tsi->tsi_u.bulk_v1;
 
                /* I should never get this step if it's unknown feature
                 * because make_session will reject unknown feature */
@@ -99,9 +102,13 @@ brw_client_init (sfw_test_instance_t *tsi)
                opc   = breq->blk_opc;
                flags = breq->blk_flags;
                len   = breq->blk_len;
-               npg   = (len + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+               off   = breq->blk_offset & ~PAGE_MASK;
+               npg   = (off + len + PAGE_SIZE - 1) >> PAGE_SHIFT;
        }
 
+       if (off % BRW_MSIZE != 0)
+               return -EINVAL;
+
        if (npg > LNET_MAX_IOV || npg <= 0)
                return -EINVAL;
 
@@ -113,8 +120,8 @@ brw_client_init (sfw_test_instance_t *tsi)
                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);
+               bulk = srpc_alloc_bulk(lnet_cpt_of_nid(tsu->tsu_dest.nid, NULL),
+                                      off, npg, len, opc == LST_BRW_READ);
                if (bulk == NULL) {
                        brw_client_fini(tsi);
                        return -ENOMEM;
@@ -132,145 +139,163 @@ brw_client_init (sfw_test_instance_t *tsi)
 
 static int brw_inject_one_error(void)
 {
-       struct timeval tv;
+       struct timespec64 ts;
 
        if (brw_inject_errors <= 0) return 0;
 
-       do_gettimeofday(&tv);
+       ktime_get_ts64(&ts);
 
-       if ((tv.tv_usec & 1) == 0) return 0;
+       if (((ts.tv_nsec / NSEC_PER_USEC) & 1) == 0)
+               return 0;
 
        return brw_inject_errors--;
 }
 
 static void
-brw_fill_page(struct page *pg, int pattern, __u64 magic)
+brw_fill_page(struct page *pg, int off, int len, int pattern, __u64 magic)
 {
-       char *addr = page_address(pg);
-        int   i;
-
-        LASSERT (addr != NULL);
+       char *addr = page_address(pg) + off;
+       int   i;
 
-        if (pattern == LST_BRW_CHECK_NONE) return;
+       LASSERT(addr != NULL);
+       LASSERT(off % BRW_MSIZE == 0 && len % BRW_MSIZE == 0);
 
-        if (magic == BRW_MAGIC)
-                magic += brw_inject_one_error();
+       if (pattern == LST_BRW_CHECK_NONE)
+               return;
 
-        if (pattern == LST_BRW_CHECK_SIMPLE) {
-                memcpy(addr, &magic, BRW_MSIZE);
-               addr += PAGE_CACHE_SIZE - BRW_MSIZE;
-                memcpy(addr, &magic, BRW_MSIZE);
-                return;
-        }
+       if (magic == BRW_MAGIC)
+               magic += brw_inject_one_error();
 
-        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;
-        }
+       if (pattern == LST_BRW_CHECK_SIMPLE) {
+               memcpy(addr, &magic, BRW_MSIZE);
+               if (len > BRW_MSIZE) {
+                       addr += len - BRW_MSIZE;
+                       memcpy(addr, &magic, BRW_MSIZE);
+               }
+               return;
+       }
 
-        LBUG ();
-        return;
+       if (pattern == LST_BRW_CHECK_FULL) {
+               for (i = 0; i < len; i += BRW_MSIZE)
+                       memcpy(addr + i, &magic, BRW_MSIZE);
+               return;
+       }
+       LBUG();
 }
 
 static int
-brw_check_page(struct page *pg, int pattern, __u64 magic)
+brw_check_page(struct page *pg, int off, int len, int pattern, __u64 magic)
 {
-       char  *addr = page_address(pg);
-        __u64  data = 0; /* make compiler happy */
-        int    i;
-
-        LASSERT (addr != NULL);
+       char  *addr = page_address(pg) + off;
+       __u64  data = 0; /* make compiler happy */
+       int    i;
 
-        if (pattern == LST_BRW_CHECK_NONE)
-                return 0;
+       LASSERT(addr != NULL);
+       LASSERT(off % BRW_MSIZE == 0 && len % BRW_MSIZE == 0);
 
-        if (pattern == LST_BRW_CHECK_SIMPLE) {
-                data = *((__u64 *) addr);
-                if (data != magic) goto bad_data;
+       if (pattern == LST_BRW_CHECK_NONE)
+               return 0;
 
-               addr += PAGE_CACHE_SIZE - BRW_MSIZE;
-                data = *((__u64 *) addr);
-                if (data != magic) goto bad_data;
+       if (pattern == LST_BRW_CHECK_SIMPLE) {
+               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;
-                }
+               if (len > BRW_MSIZE) {
+                       addr += len - BRW_MSIZE;
+                       data = *((__u64 *) addr);
+                       if (data != magic)
+                               goto bad_data;
+               }
+               return 0;
+       }
 
-                return 0;
-        }
+       if (pattern == LST_BRW_CHECK_FULL) {
+               for (i = 0; i < len; i += BRW_MSIZE) {
+                       data = *(__u64 *)(addr + i);
+                       if (data != magic)
+                               goto bad_data;
+               }
+               return 0;
+       }
 
-        LBUG ();
+       LBUG();
 
 bad_data:
-        CERROR ("Bad data in page %p: "LPX64", "LPX64" expected\n",
-                pg, data, magic);
-        return 1;
+       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)
+brw_fill_bulk(struct srpc_bulk *bk, int pattern, __u64 magic)
 {
-        int         i;
+       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);
-        }
+       for (i = 0; i < bk->bk_niov; i++) {
+               int     off;
+               int     len;
+
+               pg = bk->bk_iovs[i].kiov_page;
+               off = bk->bk_iovs[i].kiov_offset;
+               len = bk->bk_iovs[i].kiov_len;
+               brw_fill_page(pg, off, len, pattern, magic);
+       }
 }
 
 static int
-brw_check_bulk(srpc_bulk_t *bk, int pattern, __u64 magic)
+brw_check_bulk(struct srpc_bulk *bk, int pattern, __u64 magic)
 {
-        int         i;
+       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;
-                }
-        }
+       for (i = 0; i < bk->bk_niov; i++) {
+               int     off;
+               int     len;
+
+               pg = bk->bk_iovs[i].kiov_page;
+               off = bk->bk_iovs[i].kiov_offset;
+               len = bk->bk_iovs[i].kiov_len;
+               if (brw_check_page(pg, off, len, pattern, magic) != 0) {
+                       CERROR("Bulk page %p (%d/%d) is corrupted!\n",
+                              pg, i, bk->bk_niov);
+                       return 1;
+               }
+       }
 
-        return 0;
+       return 0;
 }
 
 static int
-brw_client_prep_rpc (sfw_test_unit_t *tsu,
-                     lnet_process_id_t dest, srpc_client_rpc_t **rpcpp)
+brw_client_prep_rpc(struct sfw_test_unit *tsu, struct lnet_process_id dest,
+                   struct srpc_client_rpc **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;
+       struct srpc_bulk *bulk = tsu->tsu_private;
+       struct sfw_test_instance *tsi = tsu->tsu_instance;
+       struct sfw_session *sn = tsi->tsi_batch->bat_session;
+       struct srpc_client_rpc *rpc;
+       struct srpc_brw_reqst *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;
+               struct test_bulk_req *breq = &tsi->tsi_u.bulk_v0;
 
                opc   = breq->blk_opc;
                flags = breq->blk_flags;
                npg   = breq->blk_npg;
-               len   = npg * PAGE_CACHE_SIZE;
+               len   = npg * PAGE_SIZE;
 
        } else {
-               test_bulk_req_v1_t  *breq = &tsi->tsi_u.bulk_v1;
+               struct test_bulk_req_v1 *breq = &tsi->tsi_u.bulk_v1;
+               int off;
 
                /* I should never get this step if it's unknown feature
                 * because make_session will reject unknown feature */
@@ -279,14 +304,15 @@ brw_client_prep_rpc (sfw_test_unit_t *tsu,
                opc   = breq->blk_opc;
                flags = breq->blk_flags;
                len   = breq->blk_len;
-               npg   = (len + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+               off   = breq->blk_offset;
+               npg   = (off + len + PAGE_SIZE - 1) >> PAGE_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]));
+       memcpy(&rpc->crpc_bulk, bulk, offsetof(struct srpc_bulk, bk_iovs[npg]));
        if (opc == LST_BRW_WRITE)
                brw_fill_bulk(&rpc->crpc_bulk, flags, BRW_MAGIC);
        else
@@ -302,14 +328,14 @@ brw_client_prep_rpc (sfw_test_unit_t *tsu,
 }
 
 static void
-brw_client_done_rpc(sfw_test_unit_t *tsu, srpc_client_rpc_t *rpc)
+brw_client_done_rpc(struct sfw_test_unit *tsu, struct srpc_client_rpc *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;
+       __u64 magic = BRW_MAGIC;
+       struct sfw_test_instance *tsi = tsu->tsu_instance;
+       struct sfw_session *sn = tsi->tsi_batch->bat_session;
+       struct srpc_msg *msg = &rpc->crpc_replymsg;
+       struct srpc_brw_reply *reply = &msg->msg_body.brw_reply;
+       struct srpc_brw_reqst *reqst = &rpc->crpc_reqstmsg.msg_body.brw_reqst;
 
        LASSERT(sn != NULL);
 
@@ -345,36 +371,35 @@ brw_client_done_rpc(sfw_test_unit_t *tsu, srpc_client_rpc_t *rpc)
                atomic_inc(&sn->sn_brw_errors);
                rpc->crpc_status = -EBADMSG;
        }
-
-       return;
 }
 
 static void
-brw_server_rpc_done(srpc_server_rpc_t *rpc)
+brw_server_rpc_done(struct srpc_server_rpc *rpc)
 {
-        srpc_bulk_t *blk = rpc->srpc_bulk;
+       struct srpc_bulk *blk = rpc->srpc_bulk;
 
-        if (blk == NULL) return;
+       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, "Transfered %d pages bulk data %s %s\n",
-                        blk->bk_niov, blk->bk_sink ? "from" : "to",
-                        libcfs_id2str(rpc->srpc_peer));
+       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);
+       sfw_free_pages(rpc);
 }
 
 static int
-brw_bulk_ready(srpc_server_rpc_t *rpc, int status)
+brw_bulk_ready(struct srpc_server_rpc *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;
+       __u64 magic = BRW_MAGIC;
+       struct srpc_brw_reply *reply = &rpc->srpc_replymsg.msg_body.brw_reply;
+       struct srpc_brw_reqst *reqst;
+       struct srpc_msg *reqstmsg;
 
         LASSERT (rpc->srpc_bulk != NULL);
         LASSERT (rpc->srpc_reqstbuf != NULL);
@@ -407,13 +432,13 @@ brw_bulk_ready(srpc_server_rpc_t *rpc, int status)
 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;
+       struct srpc_service *sv = rpc->srpc_scd->scd_svc;
+       struct srpc_msg *replymsg = &rpc->srpc_replymsg;
+       struct srpc_msg *reqstmsg = &rpc->srpc_reqstbuf->buf_msg;
+       struct srpc_brw_reply *reply = &replymsg->msg_body.brw_reply;
+       struct srpc_brw_reqst *reqst = &reqstmsg->msg_body.brw_reqst;
+       int npg;
+       int rc;
 
         LASSERT (sv->sv_id == SRPC_SERVICE_BRW);
 
@@ -447,14 +472,14 @@ brw_server_handle(struct srpc_server_rpc *rpc)
 
        if ((reqstmsg->msg_ses_feats & LST_FEAT_BULK_LEN) == 0) {
                /* compat with old version */
-               if ((reqst->brw_len & ~CFS_PAGE_MASK) != 0) {
+               if ((reqst->brw_len & ~PAGE_MASK) != 0) {
                        reply->brw_status = EINVAL;
                        return 0;
                }
-               npg = reqst->brw_len >> PAGE_CACHE_SHIFT;
+               npg = reqst->brw_len >> PAGE_SHIFT;
 
        } else {
-               npg = (reqst->brw_len + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+               npg = (reqst->brw_len + PAGE_SIZE - 1) >> PAGE_SHIFT;
        }
 
        replymsg->msg_ses_feats = reqstmsg->msg_ses_feats;
@@ -478,7 +503,8 @@ brw_server_handle(struct srpc_server_rpc *rpc)
         return 0;
 }
 
-sfw_test_client_ops_t brw_test_client;
+struct sfw_test_client_ops brw_test_client;
+
 void brw_init_test_client(void)
 {
         brw_test_client.tso_init       = brw_client_init;
@@ -487,10 +513,10 @@ void brw_init_test_client(void)
         brw_test_client.tso_done_rpc   = brw_client_done_rpc;
 };
 
-srpc_service_t brw_test_service;
+struct srpc_service 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;