X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lnet%2Fselftest%2Fbrw_test.c;h=9f751c7e074e73487cd3c6ee1b9fdd3a9f071d30;hb=a4bcfa9c49abae8035b05d94a09352aae01bd77d;hp=4b53784e3e29dce712c9301095b81b4e4deaa1e4;hpb=70e80ade90af09300396706b8910e196a7928520;p=fs%2Flustre-release.git diff --git a/lnet/selftest/brw_test.c b/lnet/selftest/brw_test.c index 4b53784..9f751c7 100644 --- a/lnet/selftest/brw_test.c +++ b/lnet/selftest/brw_test.c @@ -1,6 +1,4 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * +/* * GPL HEADER START * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -16,8 +14,8 @@ * 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 [sun.com URL with a - * copy of GPLv2]. + * 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 @@ -26,8 +24,10 @@ * GPL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. + * + * Copyright (c) 2012, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -40,86 +40,113 @@ #include "selftest.h" +static int brw_srv_workitems = SFW_TEST_WI_MAX; +CFS_MODULE_PARM(brw_srv_workitems, "i", int, 0644, "# BRW server workitems"); -extern int brw_inject_errors; +static int brw_inject_errors; +CFS_MODULE_PARM(brw_inject_errors, "i", int, 0644, + "# 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; + srpc_bulk_t *bulk; + sfw_test_unit_t *tsu; - LASSERT (tsi->tsi_is_client); + LASSERT(tsi->tsi_is_client); - list_for_each_entry (tsu, &tsi->tsi_units, tsu_list) { - bulk = tsu->tsu_private; - if (bulk == NULL) continue; + 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; - } + srpc_free_bulk(bulk); + tsu->tsu_private = NULL; + } } -int +static int brw_client_init (sfw_test_instance_t *tsi) { - test_bulk_req_t *breq = &tsi->tsi_u.bulk; - int flags = breq->blk_flags; - int npg = breq->blk_npg; - srpc_bulk_t *bulk; - sfw_test_unit_t *tsu; - - LASSERT (tsi->tsi_is_client); - - if (npg > LNET_MAX_IOV || npg <= 0) - return -EINVAL; - - if (breq->blk_opc != LST_BRW_READ && breq->blk_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(npg, breq->blk_opc == LST_BRW_READ); - if (bulk == NULL) { - brw_client_fini(tsi); - return -ENOMEM; - } - - tsu->tsu_private = bulk; - } - - return 0; + 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) -int -brw_inject_one_error (void) +static int brw_inject_one_error(void) { - struct timeval tv; + struct timeval tv; - if (brw_inject_errors <= 0) return 0; + if (brw_inject_errors <= 0) return 0; -#ifndef __KERNEL__ - gettimeofday(&tv, NULL); -#else - do_gettimeofday(&tv); -#endif + do_gettimeofday(&tv); - if ((tv.tv_usec & 1) == 0) return 0; + if ((tv.tv_usec & 1) == 0) return 0; - return brw_inject_errors--; + return brw_inject_errors--; } -void -brw_fill_page (cfs_page_t *pg, int pattern, __u64 magic) +static void +brw_fill_page(struct page *pg, int pattern, __u64 magic) { - char *addr = cfs_page_address(pg); + char *addr = page_address(pg); int i; LASSERT (addr != NULL); @@ -131,13 +158,13 @@ brw_fill_page (cfs_page_t *pg, int pattern, __u64 magic) if (pattern == LST_BRW_CHECK_SIMPLE) { memcpy(addr, &magic, BRW_MSIZE); - addr += CFS_PAGE_SIZE - BRW_MSIZE; + addr += PAGE_CACHE_SIZE - BRW_MSIZE; memcpy(addr, &magic, BRW_MSIZE); return; } if (pattern == LST_BRW_CHECK_FULL) { - for (i = 0; i < CFS_PAGE_SIZE / BRW_MSIZE; i++) + for (i = 0; i < PAGE_CACHE_SIZE / BRW_MSIZE; i++) memcpy(addr + i * BRW_MSIZE, &magic, BRW_MSIZE); return; } @@ -146,11 +173,11 @@ brw_fill_page (cfs_page_t *pg, int pattern, __u64 magic) return; } -int -brw_check_page (cfs_page_t *pg, int pattern, __u64 magic) +static int +brw_check_page(struct page *pg, int pattern, __u64 magic) { - char *addr = cfs_page_address(pg); - __u64 data; + char *addr = page_address(pg); + __u64 data = 0; /* make compiler happy */ int i; LASSERT (addr != NULL); @@ -162,7 +189,7 @@ brw_check_page (cfs_page_t *pg, int pattern, __u64 magic) data = *((__u64 *) addr); if (data != magic) goto bad_data; - addr += CFS_PAGE_SIZE - BRW_MSIZE; + addr += PAGE_CACHE_SIZE - BRW_MSIZE; data = *((__u64 *) addr); if (data != magic) goto bad_data; @@ -170,7 +197,7 @@ brw_check_page (cfs_page_t *pg, int pattern, __u64 magic) } if (pattern == LST_BRW_CHECK_FULL) { - for (i = 0; i < CFS_PAGE_SIZE / BRW_MSIZE; i++) { + for (i = 0; i < PAGE_CACHE_SIZE / BRW_MSIZE; i++) { data = *(((__u64 *) addr) + i); if (data != magic) goto bad_data; } @@ -186,36 +213,26 @@ bad_data: return 1; } -void -brw_fill_bulk (srpc_bulk_t *bk, int pattern, __u64 magic) +static void +brw_fill_bulk(srpc_bulk_t *bk, int pattern, __u64 magic) { int i; - cfs_page_t *pg; + struct page *pg; for (i = 0; i < bk->bk_niov; i++) { -#ifdef __KERNEL__ pg = bk->bk_iovs[i].kiov_page; -#else - LASSERT (bk->bk_pages != NULL); - pg = bk->bk_pages[i]; -#endif brw_fill_page(pg, pattern, magic); } } -int -brw_check_bulk (srpc_bulk_t *bk, int pattern, __u64 magic) +static int +brw_check_bulk(srpc_bulk_t *bk, int pattern, __u64 magic) { int i; - cfs_page_t *pg; + struct page *pg; for (i = 0; i < bk->bk_niov; i++) { -#ifdef __KERNEL__ pg = bk->bk_iovs[i].kiov_page; -#else - LASSERT (bk->bk_pages != NULL); - pg = bk->bk_pages[i]; -#endif if (brw_check_page(pg, pattern, magic) != 0) { CERROR ("Bulk page %p (%d/%d) is corrupted!\n", pg, i, bk->bk_niov); @@ -232,106 +249,128 @@ brw_client_prep_rpc (sfw_test_unit_t *tsu, { srpc_bulk_t *bulk = tsu->tsu_private; sfw_test_instance_t *tsi = tsu->tsu_instance; - test_bulk_req_t *breq = &tsi->tsi_u.bulk; - int npg = breq->blk_npg; - int flags = breq->blk_flags; - srpc_client_rpc_t *rpc; - srpc_brw_reqst_t *req; - int rc; - - LASSERT (bulk != NULL); - LASSERT (bulk->bk_niov == npg); - - rc = sfw_create_test_rpc(tsu, dest, npg, npg * CFS_PAGE_SIZE, &rpc); - if (rc != 0) return rc; - - memcpy(&rpc->crpc_bulk, bulk, offsetof(srpc_bulk_t, bk_iovs[npg])); - if (breq->blk_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 = breq->blk_opc; - req->brw_len = npg * CFS_PAGE_SIZE; - - *rpcpp = rpc; - return 0; + 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) +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 = -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: -#ifndef __KERNEL__ - rpc->crpc_bulk.bk_pages = NULL; -#endif - return; + __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); + return; + } + + 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; + return; + } + + if (reqst->brw_rw == LST_BRW_WRITE) + return; + + 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; + } + + return; } -void -brw_server_rpc_done (srpc_server_rpc_t *rpc) +static void +brw_server_rpc_done(srpc_server_rpc_t *rpc) { - srpc_bulk_t *blk = rpc->srpc_bulk; + srpc_bulk_t *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); } -int -brw_bulk_ready (srpc_server_rpc_t *rpc, int status) +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; @@ -366,14 +405,15 @@ brw_bulk_ready (srpc_server_rpc_t *rpc, int status) return 0; } -int -brw_server_handle (srpc_server_rpc_t *rpc) +static int +brw_server_handle(struct srpc_server_rpc *rpc) { - srpc_service_t *sv = rpc->srpc_service; + 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); @@ -381,31 +421,55 @@ brw_server_handle (srpc_server_rpc_t *rpc) if (reqstmsg->msg_magic != SRPC_MSG_MAGIC) { LASSERT (reqstmsg->msg_magic == __swab32(SRPC_MSG_MAGIC)); - __swab32s(&reqstmsg->msg_type); __swab32s(&reqst->brw_rw); __swab32s(&reqst->brw_len); __swab32s(&reqst->brw_flags); __swab64s(&reqst->brw_rpyid); __swab64s(&reqst->brw_bulkid); } - LASSERT (reqstmsg->msg_type == srpc_service2request(sv->sv_id)); + 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_len == 0 || (reqst->brw_len & ~CFS_PAGE_MASK) != 0 || - reqst->brw_len / CFS_PAGE_SIZE > LNET_MAX_IOV || (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; } - - reply->brw_status = 0; - rc = sfw_alloc_pages(rpc, reqst->brw_len / CFS_PAGE_SIZE, - reqst->brw_rw == LST_BRW_WRITE); - if (rc != 0) return rc; + + 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); @@ -415,18 +479,22 @@ brw_server_handle (srpc_server_rpc_t *rpc) return 0; } -sfw_test_client_ops_t brw_test_client = +sfw_test_client_ops_t brw_test_client; +void brw_init_test_client(void) { - .tso_init = brw_client_init, - .tso_fini = brw_client_fini, - .tso_prep_rpc = brw_client_prep_rpc, - .tso_done_rpc = brw_client_done_rpc, + 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 = +srpc_service_t brw_test_service; +void brw_init_test_service(void) { - .sv_name = "brw test", - .sv_handler = brw_server_handle, - .sv_bulk_ready = brw_bulk_ready, - .sv_id = SRPC_SERVICE_BRW, -}; + + 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; +}