staging: lustre: remove top level ccflags variable
[deliverable/linux.git] / drivers / staging / lustre / lnet / selftest / conrpc.c
CommitLineData
d7e09d03
PT
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.sun.com/software/products/lustre/docs/GPLv2.pdf
19 *
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
22 * have any questions.
23 *
24 * GPL HEADER END
25 */
26/*
27 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
29 *
30 * Copyright (c) 2011, 2012, Intel Corporation.
31 */
32/*
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
35 *
36 * lnet/selftest/conctl.c
37 *
38 * Console framework rpcs
39 *
40 * Author: Liang Zhen <liang@whamcloud.com>
41 */
42
43
9fdaf8c0
GKH
44#include "../../include/linux/libcfs/libcfs.h"
45#include "../../include/linux/lnet/lib-lnet.h"
d7e09d03
PT
46#include "timer.h"
47#include "conrpc.h"
48#include "console.h"
49
50void lstcon_rpc_stat_reply(lstcon_rpc_trans_t *, srpc_msg_t *,
51 lstcon_node_t *, lstcon_trans_stat_t *);
52
53static void
54lstcon_rpc_done(srpc_client_rpc_t *rpc)
55{
56 lstcon_rpc_t *crpc = (lstcon_rpc_t *)rpc->crpc_priv;
57
58 LASSERT(crpc != NULL && rpc == crpc->crp_rpc);
59 LASSERT(crpc->crp_posted && !crpc->crp_finished);
60
61 spin_lock(&rpc->crpc_lock);
62
63 if (crpc->crp_trans == NULL) {
64 /* Orphan RPC is not in any transaction,
65 * I'm just a poor body and nobody loves me */
66 spin_unlock(&rpc->crpc_lock);
67
68 /* release it */
69 lstcon_rpc_put(crpc);
70 return;
71 }
72
73 /* not an orphan RPC */
74 crpc->crp_finished = 1;
75
76 if (crpc->crp_stamp == 0) {
77 /* not aborted */
4d72b5af 78 LASSERT(crpc->crp_status == 0);
d7e09d03
PT
79
80 crpc->crp_stamp = cfs_time_current();
81 crpc->crp_status = rpc->crpc_status;
82 }
83
84 /* wakeup (transaction)thread if I'm the last RPC in the transaction */
85 if (atomic_dec_and_test(&crpc->crp_trans->tas_remaining))
86 wake_up(&crpc->crp_trans->tas_waitq);
87
88 spin_unlock(&rpc->crpc_lock);
89}
90
91int
92lstcon_rpc_init(lstcon_node_t *nd, int service, unsigned feats,
93 int bulk_npg, int bulk_len, int embedded, lstcon_rpc_t *crpc)
94{
95 crpc->crp_rpc = sfw_create_rpc(nd->nd_id, service,
96 feats, bulk_npg, bulk_len,
97 lstcon_rpc_done, (void *)crpc);
98 if (crpc->crp_rpc == NULL)
99 return -ENOMEM;
100
101 crpc->crp_trans = NULL;
102 crpc->crp_node = nd;
103 crpc->crp_posted = 0;
104 crpc->crp_finished = 0;
105 crpc->crp_unpacked = 0;
106 crpc->crp_status = 0;
107 crpc->crp_stamp = 0;
108 crpc->crp_embedded = embedded;
109 INIT_LIST_HEAD(&crpc->crp_link);
110
111 atomic_inc(&console_session.ses_rpc_counter);
112
113 return 0;
114}
115
116int
117lstcon_rpc_prep(lstcon_node_t *nd, int service, unsigned feats,
118 int bulk_npg, int bulk_len, lstcon_rpc_t **crpcpp)
119{
120 lstcon_rpc_t *crpc = NULL;
121 int rc;
122
123 spin_lock(&console_session.ses_rpc_lock);
124
125 if (!list_empty(&console_session.ses_rpc_freelist)) {
126 crpc = list_entry(console_session.ses_rpc_freelist.next,
127 lstcon_rpc_t, crp_link);
128 list_del_init(&crpc->crp_link);
129 }
130
131 spin_unlock(&console_session.ses_rpc_lock);
132
133 if (crpc == NULL) {
134 LIBCFS_ALLOC(crpc, sizeof(*crpc));
135 if (crpc == NULL)
136 return -ENOMEM;
137 }
138
139 rc = lstcon_rpc_init(nd, service, feats, bulk_npg, bulk_len, 0, crpc);
140 if (rc == 0) {
141 *crpcpp = crpc;
142 return 0;
143 }
144
145 LIBCFS_FREE(crpc, sizeof(*crpc));
146
147 return rc;
148}
149
150void
151lstcon_rpc_put(lstcon_rpc_t *crpc)
152{
153 srpc_bulk_t *bulk = &crpc->crp_rpc->crpc_bulk;
154 int i;
155
4d72b5af 156 LASSERT(list_empty(&crpc->crp_link));
d7e09d03
PT
157
158 for (i = 0; i < bulk->bk_niov; i++) {
159 if (bulk->bk_iovs[i].kiov_page == NULL)
160 continue;
161
162 __free_page(bulk->bk_iovs[i].kiov_page);
163 }
164
165 srpc_client_rpc_decref(crpc->crp_rpc);
166
167 if (crpc->crp_embedded) {
168 /* embedded RPC, don't recycle it */
169 memset(crpc, 0, sizeof(*crpc));
170 crpc->crp_embedded = 1;
171
172 } else {
173 spin_lock(&console_session.ses_rpc_lock);
174
175 list_add(&crpc->crp_link,
176 &console_session.ses_rpc_freelist);
177
178 spin_unlock(&console_session.ses_rpc_lock);
179 }
180
181 /* RPC is not alive now */
182 atomic_dec(&console_session.ses_rpc_counter);
183}
184
185void
186lstcon_rpc_post(lstcon_rpc_t *crpc)
187{
188 lstcon_rpc_trans_t *trans = crpc->crp_trans;
189
4d72b5af 190 LASSERT(trans != NULL);
d7e09d03
PT
191
192 atomic_inc(&trans->tas_remaining);
193 crpc->crp_posted = 1;
194
195 sfw_post_rpc(crpc->crp_rpc);
196}
197
198static char *
199lstcon_rpc_trans_name(int transop)
200{
201 if (transop == LST_TRANS_SESNEW)
202 return "SESNEW";
203
204 if (transop == LST_TRANS_SESEND)
205 return "SESEND";
206
207 if (transop == LST_TRANS_SESQRY)
208 return "SESQRY";
209
210 if (transop == LST_TRANS_SESPING)
211 return "SESPING";
212
213 if (transop == LST_TRANS_TSBCLIADD)
214 return "TSBCLIADD";
215
216 if (transop == LST_TRANS_TSBSRVADD)
217 return "TSBSRVADD";
218
219 if (transop == LST_TRANS_TSBRUN)
220 return "TSBRUN";
221
222 if (transop == LST_TRANS_TSBSTOP)
223 return "TSBSTOP";
224
225 if (transop == LST_TRANS_TSBCLIQRY)
226 return "TSBCLIQRY";
227
228 if (transop == LST_TRANS_TSBSRVQRY)
229 return "TSBSRVQRY";
230
231 if (transop == LST_TRANS_STATQRY)
232 return "STATQRY";
233
234 return "Unknown";
235}
236
237int
238lstcon_rpc_trans_prep(struct list_head *translist,
239 int transop, lstcon_rpc_trans_t **transpp)
240{
241 lstcon_rpc_trans_t *trans;
242
243 if (translist != NULL) {
244 list_for_each_entry(trans, translist, tas_link) {
245 /* Can't enqueue two private transaction on
246 * the same object */
247 if ((trans->tas_opc & transop) == LST_TRANS_PRIVATE)
248 return -EPERM;
249 }
250 }
251
252 /* create a trans group */
253 LIBCFS_ALLOC(trans, sizeof(*trans));
254 if (trans == NULL)
255 return -ENOMEM;
256
257 trans->tas_opc = transop;
258
259 if (translist == NULL)
260 INIT_LIST_HEAD(&trans->tas_olink);
261 else
262 list_add_tail(&trans->tas_olink, translist);
263
264 list_add_tail(&trans->tas_link, &console_session.ses_trans_list);
265
266 INIT_LIST_HEAD(&trans->tas_rpcs_list);
267 atomic_set(&trans->tas_remaining, 0);
268 init_waitqueue_head(&trans->tas_waitq);
269
270 spin_lock(&console_session.ses_rpc_lock);
271 trans->tas_features = console_session.ses_features;
272 spin_unlock(&console_session.ses_rpc_lock);
273
274 *transpp = trans;
275 return 0;
276}
277
278void
279lstcon_rpc_trans_addreq(lstcon_rpc_trans_t *trans, lstcon_rpc_t *crpc)
280{
281 list_add_tail(&crpc->crp_link, &trans->tas_rpcs_list);
282 crpc->crp_trans = trans;
283}
284
285void
286lstcon_rpc_trans_abort(lstcon_rpc_trans_t *trans, int error)
287{
288 srpc_client_rpc_t *rpc;
289 lstcon_rpc_t *crpc;
290 lstcon_node_t *nd;
291
4d72b5af 292 list_for_each_entry(crpc, &trans->tas_rpcs_list, crp_link) {
d7e09d03
PT
293 rpc = crpc->crp_rpc;
294
295 spin_lock(&rpc->crpc_lock);
296
297 if (!crpc->crp_posted || /* not posted */
298 crpc->crp_stamp != 0) { /* rpc done or aborted already */
299 if (crpc->crp_stamp == 0) {
300 crpc->crp_stamp = cfs_time_current();
301 crpc->crp_status = -EINTR;
302 }
303 spin_unlock(&rpc->crpc_lock);
304 continue;
305 }
306
307 crpc->crp_stamp = cfs_time_current();
308 crpc->crp_status = error;
309
310 spin_unlock(&rpc->crpc_lock);
311
312 sfw_abort_rpc(rpc);
313
f02e0156 314 if (error != ETIMEDOUT)
d7e09d03
PT
315 continue;
316
317 nd = crpc->crp_node;
318 if (cfs_time_after(nd->nd_stamp, crpc->crp_stamp))
319 continue;
320
321 nd->nd_stamp = crpc->crp_stamp;
322 nd->nd_state = LST_NODE_DOWN;
323 }
324}
325
326static int
327lstcon_rpc_trans_check(lstcon_rpc_trans_t *trans)
328{
329 if (console_session.ses_shutdown &&
330 !list_empty(&trans->tas_olink)) /* Not an end session RPC */
331 return 1;
332
98d1bbdd 333 return (atomic_read(&trans->tas_remaining) == 0) ? 1 : 0;
d7e09d03
PT
334}
335
336int
337lstcon_rpc_trans_postwait(lstcon_rpc_trans_t *trans, int timeout)
338{
339 lstcon_rpc_t *crpc;
340 int rc;
341
342 if (list_empty(&trans->tas_rpcs_list))
343 return 0;
344
345 if (timeout < LST_TRANS_MIN_TIMEOUT)
346 timeout = LST_TRANS_MIN_TIMEOUT;
347
348 CDEBUG(D_NET, "Transaction %s started\n",
349 lstcon_rpc_trans_name(trans->tas_opc));
350
351 /* post all requests */
4d72b5af
RK
352 list_for_each_entry(crpc, &trans->tas_rpcs_list, crp_link) {
353 LASSERT(!crpc->crp_posted);
d7e09d03
PT
354
355 lstcon_rpc_post(crpc);
356 }
357
358 mutex_unlock(&console_session.ses_mutex);
359
360 rc = wait_event_interruptible_timeout(trans->tas_waitq,
361 lstcon_rpc_trans_check(trans),
362 cfs_time_seconds(timeout));
363 rc = (rc > 0) ? 0 : ((rc < 0) ? -EINTR : -ETIMEDOUT);
364
365 mutex_lock(&console_session.ses_mutex);
366
367 if (console_session.ses_shutdown)
368 rc = -ESHUTDOWN;
369
370 if (rc != 0 || atomic_read(&trans->tas_remaining) != 0) {
371 /* treat short timeout as canceled */
372 if (rc == -ETIMEDOUT && timeout < LST_TRANS_MIN_TIMEOUT * 2)
373 rc = -EINTR;
374
375 lstcon_rpc_trans_abort(trans, rc);
376 }
377
378 CDEBUG(D_NET, "Transaction %s stopped: %d\n",
379 lstcon_rpc_trans_name(trans->tas_opc), rc);
380
381 lstcon_rpc_trans_stat(trans, lstcon_trans_stat());
382
383 return rc;
384}
385
386int
387lstcon_rpc_get_reply(lstcon_rpc_t *crpc, srpc_msg_t **msgpp)
388{
389 lstcon_node_t *nd = crpc->crp_node;
390 srpc_client_rpc_t *rpc = crpc->crp_rpc;
391 srpc_generic_reply_t *rep;
392
4d72b5af
RK
393 LASSERT(nd != NULL && rpc != NULL);
394 LASSERT(crpc->crp_stamp != 0);
d7e09d03
PT
395
396 if (crpc->crp_status != 0) {
397 *msgpp = NULL;
398 return crpc->crp_status;
399 }
400
401 *msgpp = &rpc->crpc_replymsg;
402 if (!crpc->crp_unpacked) {
403 sfw_unpack_message(*msgpp);
404 crpc->crp_unpacked = 1;
405 }
406
407 if (cfs_time_after(nd->nd_stamp, crpc->crp_stamp))
408 return 0;
409
410 nd->nd_stamp = crpc->crp_stamp;
411 rep = &(*msgpp)->msg_body.reply;
412
413 if (rep->sid.ses_nid == LNET_NID_ANY)
414 nd->nd_state = LST_NODE_UNKNOWN;
415 else if (lstcon_session_match(rep->sid))
416 nd->nd_state = LST_NODE_ACTIVE;
417 else
418 nd->nd_state = LST_NODE_BUSY;
419
420 return 0;
421}
422
423void
424lstcon_rpc_trans_stat(lstcon_rpc_trans_t *trans, lstcon_trans_stat_t *stat)
425{
426 lstcon_rpc_t *crpc;
427 srpc_msg_t *rep;
428 int error;
429
4d72b5af 430 LASSERT(stat != NULL);
d7e09d03
PT
431
432 memset(stat, 0, sizeof(*stat));
433
434 list_for_each_entry(crpc, &trans->tas_rpcs_list, crp_link) {
435 lstcon_rpc_stat_total(stat, 1);
436
4d72b5af 437 LASSERT(crpc->crp_stamp != 0);
d7e09d03
PT
438
439 error = lstcon_rpc_get_reply(crpc, &rep);
440 if (error != 0) {
441 lstcon_rpc_stat_failure(stat, 1);
442 if (stat->trs_rpc_errno == 0)
443 stat->trs_rpc_errno = -error;
444
445 continue;
446 }
447
448 lstcon_rpc_stat_success(stat, 1);
449
450 lstcon_rpc_stat_reply(trans, rep, crpc->crp_node, stat);
451 }
452
453 if (trans->tas_opc == LST_TRANS_SESNEW && stat->trs_fwk_errno == 0) {
454 stat->trs_fwk_errno =
455 lstcon_session_feats_check(trans->tas_features);
456 }
457
eac2e8c6 458 CDEBUG(D_NET, "transaction %s : success %d, failure %d, total %d, RPC error(%d), Framework error(%d)\n",
d7e09d03
PT
459 lstcon_rpc_trans_name(trans->tas_opc),
460 lstcon_rpc_stat_success(stat, 0),
461 lstcon_rpc_stat_failure(stat, 0),
462 lstcon_rpc_stat_total(stat, 0),
463 stat->trs_rpc_errno, stat->trs_fwk_errno);
464
465 return;
466}
467
468int
469lstcon_rpc_trans_interpreter(lstcon_rpc_trans_t *trans,
470 struct list_head *head_up,
471 lstcon_rpc_readent_func_t readent)
472{
473 struct list_head tmp;
474 struct list_head *next;
475 lstcon_rpc_ent_t *ent;
476 srpc_generic_reply_t *rep;
477 lstcon_rpc_t *crpc;
478 srpc_msg_t *msg;
479 lstcon_node_t *nd;
480 cfs_duration_t dur;
481 struct timeval tv;
482 int error;
483
4d72b5af 484 LASSERT(head_up != NULL);
d7e09d03
PT
485
486 next = head_up;
487
488 list_for_each_entry(crpc, &trans->tas_rpcs_list, crp_link) {
489 if (copy_from_user(&tmp, next,
490 sizeof(struct list_head)))
491 return -EFAULT;
492
493 if (tmp.next == head_up)
494 return 0;
495
496 next = tmp.next;
497
498 ent = list_entry(next, lstcon_rpc_ent_t, rpe_link);
499
4d72b5af 500 LASSERT(crpc->crp_stamp != 0);
d7e09d03
PT
501
502 error = lstcon_rpc_get_reply(crpc, &msg);
503
504 nd = crpc->crp_node;
505
506 dur = (cfs_duration_t)cfs_time_sub(crpc->crp_stamp,
507 (cfs_time_t)console_session.ses_id.ses_stamp);
508 cfs_duration_usec(dur, &tv);
509
510 if (copy_to_user(&ent->rpe_peer,
511 &nd->nd_id, sizeof(lnet_process_id_t)) ||
512 copy_to_user(&ent->rpe_stamp, &tv, sizeof(tv)) ||
513 copy_to_user(&ent->rpe_state,
514 &nd->nd_state, sizeof(nd->nd_state)) ||
515 copy_to_user(&ent->rpe_rpc_errno, &error,
516 sizeof(error)))
517 return -EFAULT;
518
519 if (error != 0)
520 continue;
521
522 /* RPC is done */
523 rep = (srpc_generic_reply_t *)&msg->msg_body.reply;
524
525 if (copy_to_user(&ent->rpe_sid,
526 &rep->sid, sizeof(lst_sid_t)) ||
527 copy_to_user(&ent->rpe_fwk_errno,
528 &rep->status, sizeof(rep->status)))
529 return -EFAULT;
530
531 if (readent == NULL)
532 continue;
533
b0834c87
RK
534 error = readent(trans->tas_opc, msg, ent);
535
536 if (error != 0)
d7e09d03
PT
537 return error;
538 }
539
540 return 0;
541}
542
543void
544lstcon_rpc_trans_destroy(lstcon_rpc_trans_t *trans)
545{
546 srpc_client_rpc_t *rpc;
547 lstcon_rpc_t *crpc;
548 lstcon_rpc_t *tmp;
549 int count = 0;
550
551 list_for_each_entry_safe(crpc, tmp, &trans->tas_rpcs_list,
552 crp_link) {
553 rpc = crpc->crp_rpc;
554
555 spin_lock(&rpc->crpc_lock);
556
557 /* free it if not posted or finished already */
558 if (!crpc->crp_posted || crpc->crp_finished) {
559 spin_unlock(&rpc->crpc_lock);
560
561 list_del_init(&crpc->crp_link);
562 lstcon_rpc_put(crpc);
563
564 continue;
565 }
566
567 /* rpcs can be still not callbacked (even LNetMDUnlink is called)
568 * because huge timeout for inaccessible network, don't make
569 * user wait for them, just abandon them, they will be recycled
570 * in callback */
571
4d72b5af 572 LASSERT(crpc->crp_status != 0);
d7e09d03
PT
573
574 crpc->crp_node = NULL;
575 crpc->crp_trans = NULL;
576 list_del_init(&crpc->crp_link);
fc831a90 577 count++;
d7e09d03
PT
578
579 spin_unlock(&rpc->crpc_lock);
580
581 atomic_dec(&trans->tas_remaining);
582 }
583
4d72b5af 584 LASSERT(atomic_read(&trans->tas_remaining) == 0);
d7e09d03
PT
585
586 list_del(&trans->tas_link);
587 if (!list_empty(&trans->tas_olink))
588 list_del(&trans->tas_olink);
589
590 CDEBUG(D_NET, "Transaction %s destroyed with %d pending RPCs\n",
591 lstcon_rpc_trans_name(trans->tas_opc), count);
592
593 LIBCFS_FREE(trans, sizeof(*trans));
594
595 return;
596}
597
598int
599lstcon_sesrpc_prep(lstcon_node_t *nd, int transop,
600 unsigned feats, lstcon_rpc_t **crpc)
601{
602 srpc_mksn_reqst_t *msrq;
603 srpc_rmsn_reqst_t *rsrq;
604 int rc;
605
606 switch (transop) {
607 case LST_TRANS_SESNEW:
608 rc = lstcon_rpc_prep(nd, SRPC_SERVICE_MAKE_SESSION,
609 feats, 0, 0, crpc);
610 if (rc != 0)
611 return rc;
612
613 msrq = &(*crpc)->crp_rpc->crpc_reqstmsg.msg_body.mksn_reqst;
614 msrq->mksn_sid = console_session.ses_id;
615 msrq->mksn_force = console_session.ses_force;
616 strncpy(msrq->mksn_name, console_session.ses_name,
617 strlen(console_session.ses_name));
618 break;
619
620 case LST_TRANS_SESEND:
621 rc = lstcon_rpc_prep(nd, SRPC_SERVICE_REMOVE_SESSION,
622 feats, 0, 0, crpc);
623 if (rc != 0)
624 return rc;
625
626 rsrq = &(*crpc)->crp_rpc->crpc_reqstmsg.msg_body.rmsn_reqst;
627 rsrq->rmsn_sid = console_session.ses_id;
628 break;
629
630 default:
631 LBUG();
632 }
633
634 return 0;
635}
636
637int
638lstcon_dbgrpc_prep(lstcon_node_t *nd, unsigned feats, lstcon_rpc_t **crpc)
639{
640 srpc_debug_reqst_t *drq;
641 int rc;
642
643 rc = lstcon_rpc_prep(nd, SRPC_SERVICE_DEBUG, feats, 0, 0, crpc);
644 if (rc != 0)
645 return rc;
646
647 drq = &(*crpc)->crp_rpc->crpc_reqstmsg.msg_body.dbg_reqst;
648
649 drq->dbg_sid = console_session.ses_id;
650 drq->dbg_flags = 0;
651
652 return rc;
653}
654
655int
656lstcon_batrpc_prep(lstcon_node_t *nd, int transop, unsigned feats,
657 lstcon_tsb_hdr_t *tsb, lstcon_rpc_t **crpc)
658{
659 lstcon_batch_t *batch;
660 srpc_batch_reqst_t *brq;
661 int rc;
662
663 rc = lstcon_rpc_prep(nd, SRPC_SERVICE_BATCH, feats, 0, 0, crpc);
664 if (rc != 0)
665 return rc;
666
667 brq = &(*crpc)->crp_rpc->crpc_reqstmsg.msg_body.bat_reqst;
668
669 brq->bar_sid = console_session.ses_id;
670 brq->bar_bid = tsb->tsb_id;
671 brq->bar_testidx = tsb->tsb_index;
672 brq->bar_opc = transop == LST_TRANS_TSBRUN ? SRPC_BATCH_OPC_RUN :
98d1bbdd 673 (transop == LST_TRANS_TSBSTOP ? SRPC_BATCH_OPC_STOP :
d7e09d03
PT
674 SRPC_BATCH_OPC_QUERY);
675
676 if (transop != LST_TRANS_TSBRUN &&
677 transop != LST_TRANS_TSBSTOP)
678 return 0;
679
4d72b5af 680 LASSERT(tsb->tsb_index == 0);
d7e09d03
PT
681
682 batch = (lstcon_batch_t *)tsb;
683 brq->bar_arg = batch->bat_arg;
684
685 return 0;
686}
687
688int
689lstcon_statrpc_prep(lstcon_node_t *nd, unsigned feats, lstcon_rpc_t **crpc)
690{
691 srpc_stat_reqst_t *srq;
692 int rc;
693
694 rc = lstcon_rpc_prep(nd, SRPC_SERVICE_QUERY_STAT, feats, 0, 0, crpc);
695 if (rc != 0)
696 return rc;
697
698 srq = &(*crpc)->crp_rpc->crpc_reqstmsg.msg_body.stat_reqst;
699
700 srq->str_sid = console_session.ses_id;
701 srq->str_type = 0; /* XXX remove it */
702
703 return 0;
704}
705
706lnet_process_id_packed_t *
707lstcon_next_id(int idx, int nkiov, lnet_kiov_t *kiov)
708{
709 lnet_process_id_packed_t *pid;
710 int i;
711
712 i = idx / SFW_ID_PER_PAGE;
713
4d72b5af 714 LASSERT(i < nkiov);
d7e09d03
PT
715
716 pid = (lnet_process_id_packed_t *)page_address(kiov[i].kiov_page);
717
718 return &pid[idx % SFW_ID_PER_PAGE];
719}
720
721int
722lstcon_dstnodes_prep(lstcon_group_t *grp, int idx,
723 int dist, int span, int nkiov, lnet_kiov_t *kiov)
724{
725 lnet_process_id_packed_t *pid;
726 lstcon_ndlink_t *ndl;
727 lstcon_node_t *nd;
728 int start;
729 int end;
730 int i = 0;
731
4d72b5af
RK
732 LASSERT(dist >= 1);
733 LASSERT(span >= 1);
734 LASSERT(grp->grp_nnode >= 1);
d7e09d03
PT
735
736 if (span > grp->grp_nnode)
737 return -EINVAL;
738
739 start = ((idx / dist) * span) % grp->grp_nnode;
740 end = ((idx / dist) * span + span - 1) % grp->grp_nnode;
741
742 list_for_each_entry(ndl, &grp->grp_ndl_list, ndl_link) {
743 nd = ndl->ndl_node;
744 if (i < start) {
fc831a90 745 i++;
d7e09d03
PT
746 continue;
747 }
748
98d1bbdd 749 if (i > (end >= start ? end : grp->grp_nnode))
d7e09d03
PT
750 break;
751
752 pid = lstcon_next_id((i - start), nkiov, kiov);
753 pid->nid = nd->nd_id.nid;
754 pid->pid = nd->nd_id.pid;
755 i++;
756 }
757
758 if (start <= end) /* done */
759 return 0;
760
761 list_for_each_entry(ndl, &grp->grp_ndl_list, ndl_link) {
762 if (i > grp->grp_nnode + end)
763 break;
764
765 nd = ndl->ndl_node;
766 pid = lstcon_next_id((i - start), nkiov, kiov);
767 pid->nid = nd->nd_id.nid;
768 pid->pid = nd->nd_id.pid;
769 i++;
770 }
771
772 return 0;
773}
774
775int
776lstcon_pingrpc_prep(lst_test_ping_param_t *param, srpc_test_reqst_t *req)
777{
778 test_ping_req_t *prq = &req->tsr_u.ping;
779
780 prq->png_size = param->png_size;
781 prq->png_flags = param->png_flags;
782 /* TODO dest */
783 return 0;
784}
785
786int
787lstcon_bulkrpc_v0_prep(lst_test_bulk_param_t *param, srpc_test_reqst_t *req)
788{
789 test_bulk_req_t *brq = &req->tsr_u.bulk_v0;
790
791 brq->blk_opc = param->blk_opc;
792 brq->blk_npg = (param->blk_size + PAGE_CACHE_SIZE - 1) / PAGE_CACHE_SIZE;
793 brq->blk_flags = param->blk_flags;
794
795 return 0;
796}
797
798int
799lstcon_bulkrpc_v1_prep(lst_test_bulk_param_t *param, srpc_test_reqst_t *req)
800{
801 test_bulk_req_v1_t *brq = &req->tsr_u.bulk_v1;
802
803 brq->blk_opc = param->blk_opc;
804 brq->blk_flags = param->blk_flags;
805 brq->blk_len = param->blk_size;
806 brq->blk_offset = 0; /* reserved */
807
808 return 0;
809}
810
811int
812lstcon_testrpc_prep(lstcon_node_t *nd, int transop, unsigned feats,
813 lstcon_test_t *test, lstcon_rpc_t **crpc)
814{
815 lstcon_group_t *sgrp = test->tes_src_grp;
816 lstcon_group_t *dgrp = test->tes_dst_grp;
817 srpc_test_reqst_t *trq;
818 srpc_bulk_t *bulk;
819 int i;
820 int npg = 0;
821 int nob = 0;
822 int rc = 0;
823
824 if (transop == LST_TRANS_TSBCLIADD) {
825 npg = sfw_id_pages(test->tes_span);
826 nob = (feats & LST_FEAT_BULK_LEN) == 0 ?
827 npg * PAGE_CACHE_SIZE :
828 sizeof(lnet_process_id_packed_t) * test->tes_span;
829 }
830
831 rc = lstcon_rpc_prep(nd, SRPC_SERVICE_TEST, feats, npg, nob, crpc);
832 if (rc != 0)
833 return rc;
834
835 trq = &(*crpc)->crp_rpc->crpc_reqstmsg.msg_body.tes_reqst;
836
837 if (transop == LST_TRANS_TSBSRVADD) {
838 int ndist = (sgrp->grp_nnode + test->tes_dist - 1) / test->tes_dist;
839 int nspan = (dgrp->grp_nnode + test->tes_span - 1) / test->tes_span;
840 int nmax = (ndist + nspan - 1) / nspan;
841
842 trq->tsr_ndest = 0;
843 trq->tsr_loop = nmax * test->tes_dist * test->tes_concur;
844
845 } else {
846 bulk = &(*crpc)->crp_rpc->crpc_bulk;
847
848 for (i = 0; i < npg; i++) {
849 int len;
850
851 LASSERT(nob > 0);
852
853 len = (feats & LST_FEAT_BULK_LEN) == 0 ?
854 PAGE_CACHE_SIZE : min_t(int, nob, PAGE_CACHE_SIZE);
855 nob -= len;
856
857 bulk->bk_iovs[i].kiov_offset = 0;
858 bulk->bk_iovs[i].kiov_len = len;
859 bulk->bk_iovs[i].kiov_page =
860 alloc_page(GFP_IOFS);
861
862 if (bulk->bk_iovs[i].kiov_page == NULL) {
863 lstcon_rpc_put(*crpc);
864 return -ENOMEM;
865 }
866 }
867
868 bulk->bk_sink = 0;
869
4d72b5af 870 LASSERT(transop == LST_TRANS_TSBCLIADD);
d7e09d03
PT
871
872 rc = lstcon_dstnodes_prep(test->tes_dst_grp,
873 test->tes_cliidx++,
874 test->tes_dist,
875 test->tes_span,
876 npg, &bulk->bk_iovs[0]);
877 if (rc != 0) {
878 lstcon_rpc_put(*crpc);
879 return rc;
880 }
881
882 trq->tsr_ndest = test->tes_span;
883 trq->tsr_loop = test->tes_loop;
884 }
885
886 trq->tsr_sid = console_session.ses_id;
887 trq->tsr_bid = test->tes_hdr.tsb_id;
888 trq->tsr_concur = test->tes_concur;
889 trq->tsr_is_client = (transop == LST_TRANS_TSBCLIADD) ? 1 : 0;
890 trq->tsr_stop_onerr = !!test->tes_stop_onerr;
891
892 switch (test->tes_type) {
893 case LST_TEST_PING:
894 trq->tsr_service = SRPC_SERVICE_PING;
895 rc = lstcon_pingrpc_prep((lst_test_ping_param_t *)
896 &test->tes_param[0], trq);
897 break;
898
899 case LST_TEST_BULK:
900 trq->tsr_service = SRPC_SERVICE_BRW;
901 if ((feats & LST_FEAT_BULK_LEN) == 0) {
902 rc = lstcon_bulkrpc_v0_prep((lst_test_bulk_param_t *)
903 &test->tes_param[0], trq);
904 } else {
905 rc = lstcon_bulkrpc_v1_prep((lst_test_bulk_param_t *)
906 &test->tes_param[0], trq);
907 }
908
909 break;
910 default:
911 LBUG();
912 break;
913 }
914
915 return rc;
916}
917
918int
919lstcon_sesnew_stat_reply(lstcon_rpc_trans_t *trans,
920 lstcon_node_t *nd, srpc_msg_t *reply)
921{
922 srpc_mksn_reply_t *mksn_rep = &reply->msg_body.mksn_reply;
923 int status = mksn_rep->mksn_status;
924
925 if (status == 0 &&
926 (reply->msg_ses_feats & ~LST_FEATS_MASK) != 0) {
927 mksn_rep->mksn_status = EPROTO;
928 status = EPROTO;
929 }
930
931 if (status == EPROTO) {
932 CNETERR("session protocol error from %s: %u\n",
933 libcfs_nid2str(nd->nd_id.nid),
934 reply->msg_ses_feats);
935 }
936
937 if (status != 0)
938 return status;
939
940 if (!trans->tas_feats_updated) {
941 trans->tas_feats_updated = 1;
942 trans->tas_features = reply->msg_ses_feats;
943 }
944
945 if (reply->msg_ses_feats != trans->tas_features) {
eac2e8c6 946 CNETERR("Framework features %x from %s is different with features on this transaction: %x\n",
d7e09d03
PT
947 reply->msg_ses_feats, libcfs_nid2str(nd->nd_id.nid),
948 trans->tas_features);
949 status = mksn_rep->mksn_status = EPROTO;
950 }
951
952 if (status == 0) {
953 /* session timeout on remote node */
954 nd->nd_timeout = mksn_rep->mksn_timeout;
955 }
956
957 return status;
958}
959
960void
961lstcon_rpc_stat_reply(lstcon_rpc_trans_t *trans, srpc_msg_t *msg,
962 lstcon_node_t *nd, lstcon_trans_stat_t *stat)
963{
964 srpc_rmsn_reply_t *rmsn_rep;
965 srpc_debug_reply_t *dbg_rep;
966 srpc_batch_reply_t *bat_rep;
967 srpc_test_reply_t *test_rep;
968 srpc_stat_reply_t *stat_rep;
969 int rc = 0;
970
971 switch (trans->tas_opc) {
972 case LST_TRANS_SESNEW:
973 rc = lstcon_sesnew_stat_reply(trans, nd, msg);
974 if (rc == 0) {
975 lstcon_sesop_stat_success(stat, 1);
976 return;
977 }
978
979 lstcon_sesop_stat_failure(stat, 1);
980 break;
981
982 case LST_TRANS_SESEND:
983 rmsn_rep = &msg->msg_body.rmsn_reply;
984 /* ESRCH is not an error for end session */
985 if (rmsn_rep->rmsn_status == 0 ||
986 rmsn_rep->rmsn_status == ESRCH) {
987 lstcon_sesop_stat_success(stat, 1);
988 return;
989 }
990
991 lstcon_sesop_stat_failure(stat, 1);
992 rc = rmsn_rep->rmsn_status;
993 break;
994
995 case LST_TRANS_SESQRY:
996 case LST_TRANS_SESPING:
997 dbg_rep = &msg->msg_body.dbg_reply;
998
999 if (dbg_rep->dbg_status == ESRCH) {
1000 lstcon_sesqry_stat_unknown(stat, 1);
1001 return;
1002 }
1003
1004 if (lstcon_session_match(dbg_rep->dbg_sid))
1005 lstcon_sesqry_stat_active(stat, 1);
1006 else
1007 lstcon_sesqry_stat_busy(stat, 1);
1008 return;
1009
1010 case LST_TRANS_TSBRUN:
1011 case LST_TRANS_TSBSTOP:
1012 bat_rep = &msg->msg_body.bat_reply;
1013
1014 if (bat_rep->bar_status == 0) {
1015 lstcon_tsbop_stat_success(stat, 1);
1016 return;
1017 }
1018
1019 if (bat_rep->bar_status == EPERM &&
1020 trans->tas_opc == LST_TRANS_TSBSTOP) {
1021 lstcon_tsbop_stat_success(stat, 1);
1022 return;
1023 }
1024
1025 lstcon_tsbop_stat_failure(stat, 1);
1026 rc = bat_rep->bar_status;
1027 break;
1028
1029 case LST_TRANS_TSBCLIQRY:
1030 case LST_TRANS_TSBSRVQRY:
1031 bat_rep = &msg->msg_body.bat_reply;
1032
1033 if (bat_rep->bar_active != 0)
1034 lstcon_tsbqry_stat_run(stat, 1);
1035 else
1036 lstcon_tsbqry_stat_idle(stat, 1);
1037
1038 if (bat_rep->bar_status == 0)
1039 return;
1040
1041 lstcon_tsbqry_stat_failure(stat, 1);
1042 rc = bat_rep->bar_status;
1043 break;
1044
1045 case LST_TRANS_TSBCLIADD:
1046 case LST_TRANS_TSBSRVADD:
1047 test_rep = &msg->msg_body.tes_reply;
1048
1049 if (test_rep->tsr_status == 0) {
1050 lstcon_tsbop_stat_success(stat, 1);
1051 return;
1052 }
1053
1054 lstcon_tsbop_stat_failure(stat, 1);
1055 rc = test_rep->tsr_status;
1056 break;
1057
1058 case LST_TRANS_STATQRY:
1059 stat_rep = &msg->msg_body.stat_reply;
1060
1061 if (stat_rep->str_status == 0) {
1062 lstcon_statqry_stat_success(stat, 1);
1063 return;
1064 }
1065
1066 lstcon_statqry_stat_failure(stat, 1);
1067 rc = stat_rep->str_status;
1068 break;
1069
1070 default:
1071 LBUG();
1072 }
1073
1074 if (stat->trs_fwk_errno == 0)
1075 stat->trs_fwk_errno = rc;
1076
1077 return;
1078}
1079
1080int
1081lstcon_rpc_trans_ndlist(struct list_head *ndlist,
1082 struct list_head *translist, int transop,
1083 void *arg, lstcon_rpc_cond_func_t condition,
1084 lstcon_rpc_trans_t **transpp)
1085{
1086 lstcon_rpc_trans_t *trans;
1087 lstcon_ndlink_t *ndl;
1088 lstcon_node_t *nd;
1089 lstcon_rpc_t *rpc;
1090 unsigned feats;
1091 int rc;
1092
1093 /* Creating session RPG for list of nodes */
1094
1095 rc = lstcon_rpc_trans_prep(translist, transop, &trans);
1096 if (rc != 0) {
1097 CERROR("Can't create transaction %d: %d\n", transop, rc);
1098 return rc;
1099 }
1100
1101 feats = trans->tas_features;
1102 list_for_each_entry(ndl, ndlist, ndl_link) {
1103 rc = condition == NULL ? 1 :
1104 condition(transop, ndl->ndl_node, arg);
1105
1106 if (rc == 0)
1107 continue;
1108
1109 if (rc < 0) {
eac2e8c6
RK
1110 CDEBUG(D_NET, "Condition error while creating RPC for transaction %d: %d\n",
1111 transop, rc);
d7e09d03
PT
1112 break;
1113 }
1114
1115 nd = ndl->ndl_node;
1116
1117 switch (transop) {
1118 case LST_TRANS_SESNEW:
1119 case LST_TRANS_SESEND:
1120 rc = lstcon_sesrpc_prep(nd, transop, feats, &rpc);
1121 break;
1122 case LST_TRANS_SESQRY:
1123 case LST_TRANS_SESPING:
1124 rc = lstcon_dbgrpc_prep(nd, feats, &rpc);
1125 break;
1126 case LST_TRANS_TSBCLIADD:
1127 case LST_TRANS_TSBSRVADD:
1128 rc = lstcon_testrpc_prep(nd, transop, feats,
1129 (lstcon_test_t *)arg, &rpc);
1130 break;
1131 case LST_TRANS_TSBRUN:
1132 case LST_TRANS_TSBSTOP:
1133 case LST_TRANS_TSBCLIQRY:
1134 case LST_TRANS_TSBSRVQRY:
1135 rc = lstcon_batrpc_prep(nd, transop, feats,
1136 (lstcon_tsb_hdr_t *)arg, &rpc);
1137 break;
1138 case LST_TRANS_STATQRY:
1139 rc = lstcon_statrpc_prep(nd, feats, &rpc);
1140 break;
1141 default:
1142 rc = -EINVAL;
1143 break;
1144 }
1145
1146 if (rc != 0) {
1147 CERROR("Failed to create RPC for transaction %s: %d\n",
1148 lstcon_rpc_trans_name(transop), rc);
1149 break;
1150 }
1151
1152 lstcon_rpc_trans_addreq(trans, rpc);
1153 }
1154
1155 if (rc == 0) {
1156 *transpp = trans;
1157 return 0;
1158 }
1159
1160 lstcon_rpc_trans_destroy(trans);
1161
1162 return rc;
1163}
1164
1165void
1166lstcon_rpc_pinger(void *arg)
1167{
1168 stt_timer_t *ptimer = (stt_timer_t *)arg;
1169 lstcon_rpc_trans_t *trans;
1170 lstcon_rpc_t *crpc;
1171 srpc_msg_t *rep;
1172 srpc_debug_reqst_t *drq;
1173 lstcon_ndlink_t *ndl;
1174 lstcon_node_t *nd;
1175 time_t intv;
1176 int count = 0;
1177 int rc;
1178
1179 /* RPC pinger is a special case of transaction,
1180 * it's called by timer at 8 seconds interval.
1181 */
1182 mutex_lock(&console_session.ses_mutex);
1183
1184 if (console_session.ses_shutdown || console_session.ses_expired) {
1185 mutex_unlock(&console_session.ses_mutex);
1186 return;
1187 }
1188
1189 if (!console_session.ses_expired &&
1190 cfs_time_current_sec() - console_session.ses_laststamp >
1191 (time_t)console_session.ses_timeout)
1192 console_session.ses_expired = 1;
1193
1194 trans = console_session.ses_ping;
1195
4d72b5af 1196 LASSERT(trans != NULL);
d7e09d03
PT
1197
1198 list_for_each_entry(ndl, &console_session.ses_ndl_list, ndl_link) {
1199 nd = ndl->ndl_node;
1200
1201 if (console_session.ses_expired) {
1202 /* idle console, end session on all nodes */
1203 if (nd->nd_state != LST_NODE_ACTIVE)
1204 continue;
1205
1206 rc = lstcon_sesrpc_prep(nd, LST_TRANS_SESEND,
1207 trans->tas_features, &crpc);
1208 if (rc != 0) {
1209 CERROR("Out of memory\n");
1210 break;
1211 }
1212
1213 lstcon_rpc_trans_addreq(trans, crpc);
1214 lstcon_rpc_post(crpc);
1215
1216 continue;
1217 }
1218
1219 crpc = &nd->nd_ping;
1220
1221 if (crpc->crp_rpc != NULL) {
4d72b5af
RK
1222 LASSERT(crpc->crp_trans == trans);
1223 LASSERT(!list_empty(&crpc->crp_link));
d7e09d03
PT
1224
1225 spin_lock(&crpc->crp_rpc->crpc_lock);
1226
1227 LASSERT(crpc->crp_posted);
1228
1229 if (!crpc->crp_finished) {
1230 /* in flight */
1231 spin_unlock(&crpc->crp_rpc->crpc_lock);
1232 continue;
1233 }
1234
1235 spin_unlock(&crpc->crp_rpc->crpc_lock);
1236
1237 lstcon_rpc_get_reply(crpc, &rep);
1238
1239 list_del_init(&crpc->crp_link);
1240
1241 lstcon_rpc_put(crpc);
1242 }
1243
1244 if (nd->nd_state != LST_NODE_ACTIVE)
1245 continue;
1246
1247 intv = cfs_duration_sec(cfs_time_sub(cfs_time_current(),
1248 nd->nd_stamp));
1249 if (intv < (time_t)nd->nd_timeout / 2)
1250 continue;
1251
1252 rc = lstcon_rpc_init(nd, SRPC_SERVICE_DEBUG,
1253 trans->tas_features, 0, 0, 1, crpc);
1254 if (rc != 0) {
1255 CERROR("Out of memory\n");
1256 break;
1257 }
1258
1259 drq = &crpc->crp_rpc->crpc_reqstmsg.msg_body.dbg_reqst;
1260
1261 drq->dbg_sid = console_session.ses_id;
1262 drq->dbg_flags = 0;
1263
1264 lstcon_rpc_trans_addreq(trans, crpc);
1265 lstcon_rpc_post(crpc);
1266
fc831a90 1267 count++;
d7e09d03
PT
1268 }
1269
1270 if (console_session.ses_expired) {
1271 mutex_unlock(&console_session.ses_mutex);
1272 return;
1273 }
1274
1275 CDEBUG(D_NET, "Ping %d nodes in session\n", count);
1276
1277 ptimer->stt_expires = (cfs_time_t)(cfs_time_current_sec() + LST_PING_INTERVAL);
1278 stt_add_timer(ptimer);
1279
1280 mutex_unlock(&console_session.ses_mutex);
1281}
1282
1283int
1284lstcon_rpc_pinger_start(void)
1285{
1286 stt_timer_t *ptimer;
1287 int rc;
1288
4d72b5af
RK
1289 LASSERT(list_empty(&console_session.ses_rpc_freelist));
1290 LASSERT(atomic_read(&console_session.ses_rpc_counter) == 0);
d7e09d03
PT
1291
1292 rc = lstcon_rpc_trans_prep(NULL, LST_TRANS_SESPING,
1293 &console_session.ses_ping);
1294 if (rc != 0) {
1295 CERROR("Failed to create console pinger\n");
1296 return rc;
1297 }
1298
1299 ptimer = &console_session.ses_ping_timer;
1300 ptimer->stt_expires = (cfs_time_t)(cfs_time_current_sec() + LST_PING_INTERVAL);
1301
1302 stt_add_timer(ptimer);
1303
1304 return 0;
1305}
1306
1307void
1308lstcon_rpc_pinger_stop(void)
1309{
4d72b5af 1310 LASSERT(console_session.ses_shutdown);
d7e09d03
PT
1311
1312 stt_del_timer(&console_session.ses_ping_timer);
1313
1314 lstcon_rpc_trans_abort(console_session.ses_ping, -ESHUTDOWN);
1315 lstcon_rpc_trans_stat(console_session.ses_ping, lstcon_trans_stat());
1316 lstcon_rpc_trans_destroy(console_session.ses_ping);
1317
1318 memset(lstcon_trans_stat(), 0, sizeof(lstcon_trans_stat_t));
1319
1320 console_session.ses_ping = NULL;
1321}
1322
1323void
1324lstcon_rpc_cleanup_wait(void)
1325{
1326 lstcon_rpc_trans_t *trans;
1327 lstcon_rpc_t *crpc;
1328 struct list_head *pacer;
1329 struct list_head zlist;
1330
1331 /* Called with hold of global mutex */
1332
4d72b5af 1333 LASSERT(console_session.ses_shutdown);
d7e09d03
PT
1334
1335 while (!list_empty(&console_session.ses_trans_list)) {
1336 list_for_each(pacer, &console_session.ses_trans_list) {
1337 trans = list_entry(pacer, lstcon_rpc_trans_t,
1338 tas_link);
1339
1340 CDEBUG(D_NET, "Session closed, wakeup transaction %s\n",
1341 lstcon_rpc_trans_name(trans->tas_opc));
1342
1343 wake_up(&trans->tas_waitq);
1344 }
1345
1346 mutex_unlock(&console_session.ses_mutex);
1347
eac2e8c6 1348 CWARN("Session is shutting down, waiting for termination of transactions\n");
d3caf4d5
PT
1349 set_current_state(TASK_UNINTERRUPTIBLE);
1350 schedule_timeout(cfs_time_seconds(1));
d7e09d03
PT
1351
1352 mutex_lock(&console_session.ses_mutex);
1353 }
1354
1355 spin_lock(&console_session.ses_rpc_lock);
1356
1357 lst_wait_until((atomic_read(&console_session.ses_rpc_counter) == 0),
1358 console_session.ses_rpc_lock,
eac2e8c6 1359 "Network is not accessible or target is down, waiting for %d console RPCs to being recycled\n",
d7e09d03
PT
1360 atomic_read(&console_session.ses_rpc_counter));
1361
1362 list_add(&zlist, &console_session.ses_rpc_freelist);
1363 list_del_init(&console_session.ses_rpc_freelist);
1364
1365 spin_unlock(&console_session.ses_rpc_lock);
1366
1367 while (!list_empty(&zlist)) {
1368 crpc = list_entry(zlist.next, lstcon_rpc_t, crp_link);
1369
1370 list_del(&crpc->crp_link);
1371 LIBCFS_FREE(crpc, sizeof(lstcon_rpc_t));
1372 }
1373}
1374
1375int
1376lstcon_rpc_module_init(void)
1377{
1378 INIT_LIST_HEAD(&console_session.ses_ping_timer.stt_list);
1379 console_session.ses_ping_timer.stt_func = lstcon_rpc_pinger;
1380 console_session.ses_ping_timer.stt_data = &console_session.ses_ping_timer;
1381
1382 console_session.ses_ping = NULL;
1383
1384 spin_lock_init(&console_session.ses_rpc_lock);
1385 atomic_set(&console_session.ses_rpc_counter, 0);
1386 INIT_LIST_HEAD(&console_session.ses_rpc_freelist);
1387
1388 return 0;
1389}
1390
1391void
1392lstcon_rpc_module_fini(void)
1393{
4d72b5af
RK
1394 LASSERT(list_empty(&console_session.ses_rpc_freelist));
1395 LASSERT(atomic_read(&console_session.ses_rpc_counter) == 0);
d7e09d03 1396}
This page took 0.282013 seconds and 5 git commands to generate.