linux/drivers/staging/lustre/lnet/selftest/selftest.h
<<
>>
Prefs
   1/*
   2 * GPL HEADER START
   3 *
   4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 only,
   8 * as published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope that it will be useful, but
  11 * WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13 * General Public License version 2 for more details (a copy is included
  14 * in the LICENSE file that accompanied this code).
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * version 2 along with this program; If not, see
  18 * http://www.gnu.org/licenses/gpl-2.0.html
  19 *
  20 * GPL HEADER END
  21 */
  22/*
  23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  24 * Use is subject to license terms.
  25 *
  26 * Copyright (c) 2012, Intel Corporation.
  27 */
  28/*
  29 * This file is part of Lustre, http://www.lustre.org/
  30 * Lustre is a trademark of Sun Microsystems, Inc.
  31 *
  32 * lnet/selftest/selftest.h
  33 *
  34 * Author: Isaac Huang <isaac@clusterfs.com>
  35 */
  36#ifndef __SELFTEST_SELFTEST_H__
  37#define __SELFTEST_SELFTEST_H__
  38
  39#define LNET_ONLY
  40
  41#include "../../include/linux/libcfs/libcfs.h"
  42#include "../../include/linux/lnet/lnet.h"
  43#include "../../include/linux/lnet/lib-lnet.h"
  44#include "../../include/linux/lnet/lib-types.h"
  45#include "../../include/linux/lnet/lnetst.h"
  46
  47#include "rpc.h"
  48#include "timer.h"
  49
  50#ifndef MADE_WITHOUT_COMPROMISE
  51#define MADE_WITHOUT_COMPROMISE
  52#endif
  53
  54#define SWI_STATE_NEWBORN               0
  55#define SWI_STATE_REPLY_SUBMITTED       1
  56#define SWI_STATE_REPLY_SENT            2
  57#define SWI_STATE_REQUEST_SUBMITTED     3
  58#define SWI_STATE_REQUEST_SENT          4
  59#define SWI_STATE_REPLY_RECEIVED        5
  60#define SWI_STATE_BULK_STARTED          6
  61#define SWI_STATE_DONE                  10
  62
  63/* forward refs */
  64struct srpc_service;
  65struct srpc_service_cd;
  66struct sfw_test_unit;
  67struct sfw_test_instance;
  68
  69/* services below SRPC_FRAMEWORK_SERVICE_MAX_ID are framework
  70 * services, e.g. create/modify session.
  71 */
  72#define SRPC_SERVICE_DEBUG              0
  73#define SRPC_SERVICE_MAKE_SESSION       1
  74#define SRPC_SERVICE_REMOVE_SESSION     2
  75#define SRPC_SERVICE_BATCH              3
  76#define SRPC_SERVICE_TEST               4
  77#define SRPC_SERVICE_QUERY_STAT         5
  78#define SRPC_SERVICE_JOIN               6
  79#define SRPC_FRAMEWORK_SERVICE_MAX_ID   10
  80/* other services start from SRPC_FRAMEWORK_SERVICE_MAX_ID+1 */
  81#define SRPC_SERVICE_BRW                11
  82#define SRPC_SERVICE_PING               12
  83#define SRPC_SERVICE_MAX_ID             12
  84
  85#define SRPC_REQUEST_PORTAL             50
  86/* a lazy portal for framework RPC requests */
  87#define SRPC_FRAMEWORK_REQUEST_PORTAL   51
  88/* all reply/bulk RDMAs go to this portal */
  89#define SRPC_RDMA_PORTAL                52
  90
  91static inline enum srpc_msg_type
  92srpc_service2request(int service)
  93{
  94        switch (service) {
  95        default:
  96                LBUG();
  97        case SRPC_SERVICE_DEBUG:
  98                return SRPC_MSG_DEBUG_REQST;
  99
 100        case SRPC_SERVICE_MAKE_SESSION:
 101                return SRPC_MSG_MKSN_REQST;
 102
 103        case SRPC_SERVICE_REMOVE_SESSION:
 104                return SRPC_MSG_RMSN_REQST;
 105
 106        case SRPC_SERVICE_BATCH:
 107                return SRPC_MSG_BATCH_REQST;
 108
 109        case SRPC_SERVICE_TEST:
 110                return SRPC_MSG_TEST_REQST;
 111
 112        case SRPC_SERVICE_QUERY_STAT:
 113                return SRPC_MSG_STAT_REQST;
 114
 115        case SRPC_SERVICE_BRW:
 116                return SRPC_MSG_BRW_REQST;
 117
 118        case SRPC_SERVICE_PING:
 119                return SRPC_MSG_PING_REQST;
 120
 121        case SRPC_SERVICE_JOIN:
 122                return SRPC_MSG_JOIN_REQST;
 123        }
 124}
 125
 126static inline enum srpc_msg_type
 127srpc_service2reply(int service)
 128{
 129        return srpc_service2request(service) + 1;
 130}
 131
 132enum srpc_event_type {
 133        SRPC_BULK_REQ_RCVD   = 1, /* passive bulk request(PUT sink/GET source)
 134                                   * received
 135                                   */
 136        SRPC_BULK_PUT_SENT   = 2, /* active bulk PUT sent (source) */
 137        SRPC_BULK_GET_RPLD   = 3, /* active bulk GET replied (sink) */
 138        SRPC_REPLY_RCVD      = 4, /* incoming reply received */
 139        SRPC_REPLY_SENT      = 5, /* outgoing reply sent */
 140        SRPC_REQUEST_RCVD    = 6, /* incoming request received */
 141        SRPC_REQUEST_SENT    = 7, /* outgoing request sent */
 142};
 143
 144/* RPC event */
 145struct srpc_event {
 146        enum srpc_event_type    ev_type;        /* what's up */
 147        lnet_event_kind_t ev_lnet;   /* LNet event type */
 148        int               ev_fired;  /* LNet event fired? */
 149        int               ev_status; /* LNet event status */
 150        void              *ev_data;  /* owning server/client RPC */
 151};
 152
 153/* bulk descriptor */
 154struct srpc_bulk {
 155        int              bk_len;     /* len of bulk data */
 156        lnet_handle_md_t bk_mdh;
 157        int              bk_sink;    /* sink/source */
 158        int              bk_niov;    /* # iov in bk_iovs */
 159        lnet_kiov_t      bk_iovs[0];
 160};
 161
 162/* message buffer descriptor */
 163struct srpc_buffer {
 164        struct list_head  buf_list; /* chain on srpc_service::*_msgq */
 165        struct srpc_msg   buf_msg;
 166        lnet_handle_md_t  buf_mdh;
 167        lnet_nid_t        buf_self;
 168        lnet_process_id_t buf_peer;
 169};
 170
 171struct swi_workitem;
 172typedef int (*swi_action_t) (struct swi_workitem *);
 173
 174struct swi_workitem {
 175        struct cfs_wi_sched *swi_sched;
 176        struct cfs_workitem swi_workitem;
 177        swi_action_t        swi_action;
 178        int                 swi_state;
 179};
 180
 181/* server-side state of a RPC */
 182struct srpc_server_rpc {
 183        /* chain on srpc_service::*_rpcq */
 184        struct list_head       srpc_list;
 185        struct srpc_service_cd *srpc_scd;
 186        struct swi_workitem     srpc_wi;
 187        struct srpc_event       srpc_ev;        /* bulk/reply event */
 188        lnet_nid_t             srpc_self;
 189        lnet_process_id_t      srpc_peer;
 190        struct srpc_msg         srpc_replymsg;
 191        lnet_handle_md_t       srpc_replymdh;
 192        struct srpc_buffer      *srpc_reqstbuf;
 193        struct srpc_bulk        *srpc_bulk;
 194
 195        unsigned int           srpc_aborted; /* being given up */
 196        int                    srpc_status;
 197        void                   (*srpc_done)(struct srpc_server_rpc *);
 198};
 199
 200/* client-side state of a RPC */
 201struct srpc_client_rpc {
 202        struct list_head  crpc_list;      /* chain on user's lists */
 203        spinlock_t        crpc_lock;      /* serialize */
 204        int               crpc_service;
 205        atomic_t          crpc_refcount;
 206        int               crpc_timeout;   /* # seconds to wait for reply */
 207        struct stt_timer       crpc_timer;
 208        struct swi_workitem     crpc_wi;
 209        lnet_process_id_t crpc_dest;
 210
 211        void              (*crpc_done)(struct srpc_client_rpc *);
 212        void              (*crpc_fini)(struct srpc_client_rpc *);
 213        int               crpc_status;    /* completion status */
 214        void              *crpc_priv;     /* caller data */
 215
 216        /* state flags */
 217        unsigned int      crpc_aborted:1; /* being given up */
 218        unsigned int      crpc_closed:1;  /* completed */
 219
 220        /* RPC events */
 221        struct srpc_event       crpc_bulkev;    /* bulk event */
 222        struct srpc_event       crpc_reqstev;   /* request event */
 223        struct srpc_event       crpc_replyev;   /* reply event */
 224
 225        /* bulk, request(reqst), and reply exchanged on wire */
 226        struct srpc_msg         crpc_reqstmsg;
 227        struct srpc_msg         crpc_replymsg;
 228        lnet_handle_md_t  crpc_reqstmdh;
 229        lnet_handle_md_t  crpc_replymdh;
 230        struct srpc_bulk        crpc_bulk;
 231};
 232
 233#define srpc_client_rpc_size(rpc)                                       \
 234offsetof(struct srpc_client_rpc, crpc_bulk.bk_iovs[(rpc)->crpc_bulk.bk_niov])
 235
 236#define srpc_client_rpc_addref(rpc)                                     \
 237do {                                                                    \
 238        CDEBUG(D_NET, "RPC[%p] -> %s (%d)++\n",                         \
 239               (rpc), libcfs_id2str((rpc)->crpc_dest),                  \
 240               atomic_read(&(rpc)->crpc_refcount));                     \
 241        LASSERT(atomic_read(&(rpc)->crpc_refcount) > 0);                \
 242        atomic_inc(&(rpc)->crpc_refcount);                              \
 243} while (0)
 244
 245#define srpc_client_rpc_decref(rpc)                                     \
 246do {                                                                    \
 247        CDEBUG(D_NET, "RPC[%p] -> %s (%d)--\n",                         \
 248               (rpc), libcfs_id2str((rpc)->crpc_dest),                  \
 249               atomic_read(&(rpc)->crpc_refcount));                     \
 250        LASSERT(atomic_read(&(rpc)->crpc_refcount) > 0);                \
 251        if (atomic_dec_and_test(&(rpc)->crpc_refcount))                 \
 252                srpc_destroy_client_rpc(rpc);                           \
 253} while (0)
 254
 255#define srpc_event_pending(rpc)   (!(rpc)->crpc_bulkev.ev_fired ||      \
 256                                   !(rpc)->crpc_reqstev.ev_fired ||     \
 257                                   !(rpc)->crpc_replyev.ev_fired)
 258
 259/* CPU partition data of srpc service */
 260struct srpc_service_cd {
 261        /** serialize */
 262        spinlock_t              scd_lock;
 263        /** backref to service */
 264        struct srpc_service     *scd_svc;
 265        /** event buffer */
 266        struct srpc_event       scd_ev;
 267        /** free RPC descriptors */
 268        struct list_head        scd_rpc_free;
 269        /** in-flight RPCs */
 270        struct list_head        scd_rpc_active;
 271        /** workitem for posting buffer */
 272        struct swi_workitem     scd_buf_wi;
 273        /** CPT id */
 274        int                     scd_cpt;
 275        /** error code for scd_buf_wi */
 276        int                     scd_buf_err;
 277        /** timestamp for scd_buf_err */
 278        time64_t                scd_buf_err_stamp;
 279        /** total # request buffers */
 280        int                     scd_buf_total;
 281        /** # posted request buffers */
 282        int                     scd_buf_nposted;
 283        /** in progress of buffer posting */
 284        int                     scd_buf_posting;
 285        /** allocate more buffers if scd_buf_nposted < scd_buf_low */
 286        int                     scd_buf_low;
 287        /** increase/decrease some buffers */
 288        int                     scd_buf_adjust;
 289        /** posted message buffers */
 290        struct list_head        scd_buf_posted;
 291        /** blocked for RPC descriptor */
 292        struct list_head        scd_buf_blocked;
 293};
 294
 295/* number of server workitems (mini-thread) for testing service */
 296#define SFW_TEST_WI_MIN         256
 297#define SFW_TEST_WI_MAX         2048
 298/* extra buffers for tolerating buggy peers, or unbalanced number
 299 * of peers between partitions
 300 */
 301#define SFW_TEST_WI_EXTRA       64
 302
 303/* number of server workitems (mini-thread) for framework service */
 304#define SFW_FRWK_WI_MIN         16
 305#define SFW_FRWK_WI_MAX         256
 306
 307struct srpc_service {
 308        int                     sv_id;          /* service id */
 309        const char              *sv_name;       /* human readable name */
 310        int                     sv_wi_total;    /* total server workitems */
 311        int                     sv_shuttingdown;
 312        int                     sv_ncpts;
 313        /* percpt data for srpc_service */
 314        struct srpc_service_cd  **sv_cpt_data;
 315        /* Service callbacks:
 316         * - sv_handler: process incoming RPC request
 317         * - sv_bulk_ready: notify bulk data
 318         */
 319        int (*sv_handler)(struct srpc_server_rpc *);
 320        int (*sv_bulk_ready)(struct srpc_server_rpc *, int);
 321};
 322
 323struct sfw_session {
 324        struct list_head sn_list;    /* chain on fw_zombie_sessions */
 325        lst_sid_t        sn_id;      /* unique identifier */
 326        unsigned int     sn_timeout; /* # seconds' inactivity to expire */
 327        int              sn_timer_active;
 328        unsigned int     sn_features;
 329        struct stt_timer      sn_timer;
 330        struct list_head sn_batches; /* list of batches */
 331        char             sn_name[LST_NAME_SIZE];
 332        atomic_t         sn_refcount;
 333        atomic_t         sn_brw_errors;
 334        atomic_t         sn_ping_errors;
 335        unsigned long    sn_started;
 336};
 337
 338#define sfw_sid_equal(sid0, sid1)     ((sid0).ses_nid == (sid1).ses_nid && \
 339                                       (sid0).ses_stamp == (sid1).ses_stamp)
 340
 341struct sfw_batch {
 342        struct list_head bat_list;      /* chain on sn_batches */
 343        lst_bid_t        bat_id;        /* batch id */
 344        int              bat_error;     /* error code of batch */
 345        struct sfw_session      *bat_session;   /* batch's session */
 346        atomic_t         bat_nactive;   /* # of active tests */
 347        struct list_head bat_tests;     /* test instances */
 348};
 349
 350struct sfw_test_client_ops {
 351        int  (*tso_init)(struct sfw_test_instance *tsi); /* initialize test
 352                                                          * client
 353                                                          */
 354        void (*tso_fini)(struct sfw_test_instance *tsi); /* finalize test
 355                                                          * client
 356                                                          */
 357        int  (*tso_prep_rpc)(struct sfw_test_unit *tsu,
 358                             lnet_process_id_t dest,
 359                             struct srpc_client_rpc **rpc);     /* prep a tests rpc */
 360        void (*tso_done_rpc)(struct sfw_test_unit *tsu,
 361                             struct srpc_client_rpc *rpc);      /* done a test rpc */
 362};
 363
 364struct sfw_test_instance {
 365        struct list_head           tsi_list;            /* chain on batch */
 366        int                        tsi_service;         /* test type */
 367        struct sfw_batch                *tsi_batch;     /* batch */
 368        struct sfw_test_client_ops      *tsi_ops;       /* test client operation
 369                                                         */
 370
 371        /* public parameter for all test units */
 372        unsigned int               tsi_is_client:1;     /* is test client */
 373        unsigned int               tsi_stoptsu_onerr:1; /* stop tsu on error */
 374        int                        tsi_concur;          /* concurrency */
 375        int                        tsi_loop;            /* loop count */
 376
 377        /* status of test instance */
 378        spinlock_t                 tsi_lock;            /* serialize */
 379        unsigned int               tsi_stopping:1;      /* test is stopping */
 380        atomic_t                   tsi_nactive;         /* # of active test
 381                                                         * unit
 382                                                         */
 383        struct list_head           tsi_units;           /* test units */
 384        struct list_head           tsi_free_rpcs;       /* free rpcs */
 385        struct list_head           tsi_active_rpcs;     /* active rpcs */
 386
 387        union {
 388                struct test_ping_req    ping;           /* ping parameter */
 389                struct test_bulk_req    bulk_v0;        /* bulk parameter */
 390                struct test_bulk_req_v1 bulk_v1;        /* bulk v1 parameter */
 391        } tsi_u;
 392};
 393
 394/*
 395 * XXX: trailing (PAGE_SIZE % sizeof(lnet_process_id_t)) bytes at the end of
 396 * pages are not used
 397 */
 398#define SFW_MAX_CONCUR     LST_MAX_CONCUR
 399#define SFW_ID_PER_PAGE    (PAGE_SIZE / sizeof(lnet_process_id_packed_t))
 400#define SFW_MAX_NDESTS     (LNET_MAX_IOV * SFW_ID_PER_PAGE)
 401#define sfw_id_pages(n)    (((n) + SFW_ID_PER_PAGE - 1) / SFW_ID_PER_PAGE)
 402
 403struct sfw_test_unit {
 404        struct list_head    tsu_list;      /* chain on lst_test_instance */
 405        lnet_process_id_t   tsu_dest;      /* id of dest node */
 406        int                 tsu_loop;      /* loop count of the test */
 407        struct sfw_test_instance        *tsu_instance; /* pointer to test instance */
 408        void                *tsu_private;  /* private data */
 409        struct swi_workitem     tsu_worker;     /* workitem of the test unit */
 410};
 411
 412struct sfw_test_case {
 413        struct list_head      tsc_list;         /* chain on fw_tests */
 414        struct srpc_service             *tsc_srv_service;       /* test service */
 415        struct sfw_test_client_ops      *tsc_cli_ops;   /* ops of test client */
 416};
 417
 418struct srpc_client_rpc *
 419sfw_create_rpc(lnet_process_id_t peer, int service,
 420               unsigned int features, int nbulkiov, int bulklen,
 421               void (*done)(struct srpc_client_rpc *), void *priv);
 422int sfw_create_test_rpc(struct sfw_test_unit *tsu,
 423                        lnet_process_id_t peer, unsigned int features,
 424                        int nblk, int blklen, struct srpc_client_rpc **rpc);
 425void sfw_abort_rpc(struct srpc_client_rpc *rpc);
 426void sfw_post_rpc(struct srpc_client_rpc *rpc);
 427void sfw_client_rpc_done(struct srpc_client_rpc *rpc);
 428void sfw_unpack_message(struct srpc_msg *msg);
 429void sfw_free_pages(struct srpc_server_rpc *rpc);
 430void sfw_add_bulk_page(struct srpc_bulk *bk, struct page *pg, int i);
 431int sfw_alloc_pages(struct srpc_server_rpc *rpc, int cpt, int npages, int len,
 432                    int sink);
 433int sfw_make_session(struct srpc_mksn_reqst *request,
 434                     struct srpc_mksn_reply *reply);
 435
 436struct srpc_client_rpc *
 437srpc_create_client_rpc(lnet_process_id_t peer, int service,
 438                       int nbulkiov, int bulklen,
 439                       void (*rpc_done)(struct srpc_client_rpc *),
 440                       void (*rpc_fini)(struct srpc_client_rpc *), void *priv);
 441void srpc_post_rpc(struct srpc_client_rpc *rpc);
 442void srpc_abort_rpc(struct srpc_client_rpc *rpc, int why);
 443void srpc_free_bulk(struct srpc_bulk *bk);
 444struct srpc_bulk *srpc_alloc_bulk(int cpt, unsigned int off,
 445                                  unsigned int bulk_npg, unsigned int bulk_len,
 446                                  int sink);
 447int srpc_send_rpc(struct swi_workitem *wi);
 448int srpc_send_reply(struct srpc_server_rpc *rpc);
 449int srpc_add_service(struct srpc_service *sv);
 450int srpc_remove_service(struct srpc_service *sv);
 451void srpc_shutdown_service(struct srpc_service *sv);
 452void srpc_abort_service(struct srpc_service *sv);
 453int srpc_finish_service(struct srpc_service *sv);
 454int srpc_service_add_buffers(struct srpc_service *sv, int nbuffer);
 455void srpc_service_remove_buffers(struct srpc_service *sv, int nbuffer);
 456void srpc_get_counters(srpc_counters_t *cnt);
 457void srpc_set_counters(const srpc_counters_t *cnt);
 458
 459extern struct cfs_wi_sched *lst_sched_serial;
 460extern struct cfs_wi_sched **lst_sched_test;
 461
 462static inline int
 463srpc_serv_is_framework(struct srpc_service *svc)
 464{
 465        return svc->sv_id < SRPC_FRAMEWORK_SERVICE_MAX_ID;
 466}
 467
 468static inline int
 469swi_wi_action(struct cfs_workitem *wi)
 470{
 471        struct swi_workitem *swi;
 472
 473        swi = container_of(wi, struct swi_workitem, swi_workitem);
 474
 475        return swi->swi_action(swi);
 476}
 477
 478static inline void
 479swi_init_workitem(struct swi_workitem *swi, void *data,
 480                  swi_action_t action, struct cfs_wi_sched *sched)
 481{
 482        swi->swi_sched = sched;
 483        swi->swi_action = action;
 484        swi->swi_state = SWI_STATE_NEWBORN;
 485        cfs_wi_init(&swi->swi_workitem, data, swi_wi_action);
 486}
 487
 488static inline void
 489swi_schedule_workitem(struct swi_workitem *wi)
 490{
 491        cfs_wi_schedule(wi->swi_sched, &wi->swi_workitem);
 492}
 493
 494static inline void
 495swi_exit_workitem(struct swi_workitem *swi)
 496{
 497        cfs_wi_exit(swi->swi_sched, &swi->swi_workitem);
 498}
 499
 500static inline int
 501swi_deschedule_workitem(struct swi_workitem *swi)
 502{
 503        return cfs_wi_deschedule(swi->swi_sched, &swi->swi_workitem);
 504}
 505
 506int sfw_startup(void);
 507int srpc_startup(void);
 508void sfw_shutdown(void);
 509void srpc_shutdown(void);
 510
 511static inline void
 512srpc_destroy_client_rpc(struct srpc_client_rpc *rpc)
 513{
 514        LASSERT(rpc);
 515        LASSERT(!srpc_event_pending(rpc));
 516        LASSERT(!atomic_read(&rpc->crpc_refcount));
 517
 518        if (!rpc->crpc_fini)
 519                LIBCFS_FREE(rpc, srpc_client_rpc_size(rpc));
 520        else
 521                (*rpc->crpc_fini)(rpc);
 522}
 523
 524static inline void
 525srpc_init_client_rpc(struct srpc_client_rpc *rpc, lnet_process_id_t peer,
 526                     int service, int nbulkiov, int bulklen,
 527                     void (*rpc_done)(struct srpc_client_rpc *),
 528                     void (*rpc_fini)(struct srpc_client_rpc *), void *priv)
 529{
 530        LASSERT(nbulkiov <= LNET_MAX_IOV);
 531
 532        memset(rpc, 0, offsetof(struct srpc_client_rpc,
 533                                crpc_bulk.bk_iovs[nbulkiov]));
 534
 535        INIT_LIST_HEAD(&rpc->crpc_list);
 536        swi_init_workitem(&rpc->crpc_wi, rpc, srpc_send_rpc,
 537                          lst_sched_test[lnet_cpt_of_nid(peer.nid)]);
 538        spin_lock_init(&rpc->crpc_lock);
 539        atomic_set(&rpc->crpc_refcount, 1); /* 1 ref for caller */
 540
 541        rpc->crpc_dest = peer;
 542        rpc->crpc_priv = priv;
 543        rpc->crpc_service = service;
 544        rpc->crpc_bulk.bk_len = bulklen;
 545        rpc->crpc_bulk.bk_niov = nbulkiov;
 546        rpc->crpc_done = rpc_done;
 547        rpc->crpc_fini = rpc_fini;
 548        LNetInvalidateHandle(&rpc->crpc_reqstmdh);
 549        LNetInvalidateHandle(&rpc->crpc_replymdh);
 550        LNetInvalidateHandle(&rpc->crpc_bulk.bk_mdh);
 551
 552        /* no event is expected at this point */
 553        rpc->crpc_bulkev.ev_fired = 1;
 554        rpc->crpc_reqstev.ev_fired = 1;
 555        rpc->crpc_replyev.ev_fired = 1;
 556
 557        rpc->crpc_reqstmsg.msg_magic = SRPC_MSG_MAGIC;
 558        rpc->crpc_reqstmsg.msg_version = SRPC_MSG_VERSION;
 559        rpc->crpc_reqstmsg.msg_type = srpc_service2request(service);
 560}
 561
 562static inline const char *
 563swi_state2str(int state)
 564{
 565#define STATE2STR(x) case x: return #x
 566        switch (state) {
 567        default:
 568                LBUG();
 569        STATE2STR(SWI_STATE_NEWBORN);
 570        STATE2STR(SWI_STATE_REPLY_SUBMITTED);
 571        STATE2STR(SWI_STATE_REPLY_SENT);
 572        STATE2STR(SWI_STATE_REQUEST_SUBMITTED);
 573        STATE2STR(SWI_STATE_REQUEST_SENT);
 574        STATE2STR(SWI_STATE_REPLY_RECEIVED);
 575        STATE2STR(SWI_STATE_BULK_STARTED);
 576        STATE2STR(SWI_STATE_DONE);
 577        }
 578#undef STATE2STR
 579}
 580
 581#define selftest_wait_events()                                  \
 582        do {                                                    \
 583                set_current_state(TASK_UNINTERRUPTIBLE);        \
 584                schedule_timeout(cfs_time_seconds(1) / 10);     \
 585        } while (0)
 586
 587#define lst_wait_until(cond, lock, fmt, ...)                            \
 588do {                                                                    \
 589        int __I = 2;                                                    \
 590        while (!(cond)) {                                               \
 591                CDEBUG(is_power_of_2(++__I) ? D_WARNING : D_NET,        \
 592                       fmt, ## __VA_ARGS__);                            \
 593                spin_unlock(&(lock));                                   \
 594                                                                        \
 595                selftest_wait_events();                                 \
 596                                                                        \
 597                spin_lock(&(lock));                                     \
 598        }                                                               \
 599} while (0)
 600
 601static inline void
 602srpc_wait_service_shutdown(struct srpc_service *sv)
 603{
 604        int i = 2;
 605
 606        LASSERT(sv->sv_shuttingdown);
 607
 608        while (!srpc_finish_service(sv)) {
 609                i++;
 610                CDEBUG(((i & -i) == i) ? D_WARNING : D_NET,
 611                       "Waiting for %s service to shutdown...\n",
 612                       sv->sv_name);
 613                selftest_wait_events();
 614        }
 615}
 616
 617extern struct sfw_test_client_ops brw_test_client;
 618void brw_init_test_client(void);
 619
 620extern struct srpc_service brw_test_service;
 621void brw_init_test_service(void);
 622
 623extern struct sfw_test_client_ops ping_test_client;
 624void ping_init_test_client(void);
 625
 626extern struct srpc_service ping_test_service;
 627void ping_init_test_service(void);
 628
 629#endif /* __SELFTEST_SELFTEST_H__ */
 630