Whamcloud - gitweb
c027d7a8a3da0b6e5429dd188853277e893b6dda
[fs/lustre-release.git] / lnet / klnds / kfilnd / kfilnd.h
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 2022 Hewlett Packard Enterprise Development LP
24  */
25 /*
26  * This file is part of Lustre, http://www.lustre.org/
27  */
28 /*
29  * kfilnd main interface.
30  */
31
32 #ifndef _KFILND_
33 #define _KFILND_
34
35 #include <linux/version.h>
36 #include <linux/module.h>
37 #include <linux/kernel.h>
38 #include <linux/kthread.h>
39 #include <linux/mm.h>
40 #include <linux/string.h>
41 #include <linux/stat.h>
42 #include <linux/errno.h>
43 #include <linux/unistd.h>
44 #include <linux/uio.h>
45 #include <linux/rwsem.h>
46 #include <linux/mutex.h>
47 #include <linux/rhashtable.h>
48 #include <linux/workqueue.h>
49 #include <linux/debugfs.h>
50 #include <linux/seq_file.h>
51 #include <linux/ktime.h>
52
53 #include <asm/uaccess.h>
54 #include <asm/io.h>
55
56 #include <linux/init.h>
57 #include <linux/fs.h>
58 #include <linux/file.h>
59 #include <linux/stat.h>
60 #include <linux/list.h>
61 #include <linux/kmod.h>
62 #include <linux/sysctl.h>
63 #include <linux/pci.h>
64
65 #include <net/sock.h>
66 #include <linux/in.h>
67
68 #define KFILND_VERSION "0.2.0"
69
70 #define DEBUG_SUBSYSTEM S_LND
71
72 #include <libcfs/libcfs.h>
73 #include <lnet/lib-lnet.h>
74 #include "kfi_endpoint.h"
75 #include "kfi_errno.h"
76 #include "kfi_rma.h"
77 #include "kfi_tagged.h"
78 #include "kfi_cxi_ext.h"
79
80 /* KFILND CFS fail range 0xF100 - 0xF1FF. */
81
82 #define CFS_KFI_FAIL_SEND_EVENT 0xF100
83 #define CFS_KFI_FAIL_READ_EVENT 0xF101
84 #define CFS_KFI_FAIL_WRITE_EVENT 0xF102
85 #define CFS_KFI_FAIL_TAGGED_SEND_EVENT 0xF103
86 #define CFS_KFI_FAIL_TAGGED_RECV_EVENT 0xF104
87 #define CFS_KFI_FAIL_BULK_TIMEOUT 0xF105
88 #define CFS_KFI_FAIL_SEND 0xF106
89 #define CFS_KFI_FAIL_READ 0xF107
90 #define CFS_KFI_FAIL_WRITE 0xF108
91 #define CFS_KFI_FAIL_TAGGED_SEND 0xF109
92 #define CFS_KFI_FAIL_TAGGED_RECV 0xF10A
93 #define CFS_KFI_FAIL_SEND_EAGAIN 0xF10B
94 #define CFS_KFI_FAIL_READ_EAGAIN 0xF10C
95 #define CFS_KFI_FAIL_WRITE_EAGAIN 0xF10D
96 #define CFS_KFI_FAIL_TAGGED_SEND_EAGAIN 0xF10E
97 #define CFS_KFI_FAIL_TAGGED_RECV_EAGAIN 0xF10F
98 #define CFS_KFI_FAIL_TAGGED_RECV_CANCEL_EAGAIN 0xF110
99 #define CFS_KFI_FAIL_RECV_EAGAIN 0xF111
100 #define CFS_KFI_FAIL_RECV 0xF112
101 #define CFS_KFI_FAIL_MSG_UNPACK 0xF113
102 #define CFS_KFI_FAIL_MSG_TYPE 0xF114
103
104 /* Maximum number of transaction keys supported. */
105 #define KFILND_EP_KEY_BITS 16U
106 #define KFILND_EP_KEY_MAX (BIT(KFILND_EP_KEY_BITS) - 1)
107
108 /* Some constants which should be turned into tunables */
109 #define KFILND_IMMEDIATE_MSG_SIZE 4096
110
111 #define KFILND_MY_PROCID 49152
112
113 /* 256 Rx contexts max */
114 #define KFILND_FAB_RX_CTX_BITS 8
115
116 /* Get the KFI base address from a KFI RX address. RX context information is
117  * stored in the MSBs of the KFI address.
118  */
119 #define KFILND_BASE_ADDR(addr) \
120         ((addr) & ((1UL << (64 - KFILND_FAB_RX_CTX_BITS)) - 1))
121
122 /* States used by all kfilnd structures */
123 enum kfilnd_object_states {
124         KFILND_STATE_UNINITIALIZED,
125         KFILND_STATE_INITIALIZED,
126         KFILND_STATE_SHUTTING_DOWN
127 };
128
129 enum kfilnd_ni_lnd_tunables_attr {
130         LNET_NET_KFILND_TUNABLES_ATTR_UNSPEC = 0,
131
132         LNET_NET_KFILND_TUNABLES_ATTR_PROV_MAJOR,
133         LNET_NET_KFILND_TUNABLES_ATTR_PROV_MINOR,
134         LNET_NET_KFILND_TUNABLES_ATTR_AUTH_KEY,
135         __LNET_NET_KFILND_TUNABLES_ATTR_MAX_PLUS_ONE,
136 };
137
138 #define LNET_NET_KFILND_TUNABLES_ATTR_MAX (__LNET_NET_KFILND_TUNABLES_ATTR_MAX_PLUS_ONE - 1)
139
140 extern struct dentry *kfilnd_debug_dir;
141 extern const struct file_operations kfilnd_initiator_state_stats_file_ops;
142 extern const struct file_operations kfilnd_target_state_stats_file_ops;
143 extern const struct file_operations kfilnd_target_stats_file_ops;
144 extern const struct file_operations kfilnd_initiator_stats_file_ops;
145 extern const struct file_operations kfilnd_reset_stats_file_ops;
146
147 extern struct workqueue_struct *kfilnd_wq;
148
149 extern unsigned int cksum;
150 extern unsigned int tx_scale_factor;
151 extern unsigned int rx_cq_scale_factor;
152 extern unsigned int tx_cq_scale_factor;
153 extern unsigned int eq_size;
154 extern unsigned int immediate_rx_buf_count;
155
156 int kfilnd_tunables_setup(struct lnet_ni *ni);
157 int kfilnd_tunables_init(void);
158
159 struct kfilnd_transaction;
160 struct kfilnd_ep;
161 struct kfilnd_dev;
162
163 /* Multi-receive buffers for immediate receives */
164 struct kfilnd_immediate_buffer {
165         void *immed_buf;
166         size_t immed_buf_size;
167         struct page *immed_buf_page;
168         atomic_t immed_ref;
169         bool immed_no_repost;
170         struct list_head replay_entry;
171         struct kfilnd_ep *immed_end;
172 };
173
174 extern atomic_t kfilnd_rx_count;
175
176 struct kfilnd_cq;
177
178 struct kfilnd_cq_work {
179         struct kfilnd_cq *cq;
180         unsigned int work_cpu;
181         struct work_struct work;
182 };
183
184 struct kfilnd_cq {
185         struct kfilnd_ep *ep;
186         struct kfid_cq *cq;
187         unsigned int cq_work_count;
188         struct kfilnd_cq_work cq_works[];
189 };
190
191 struct kfilnd_ep {
192         /* The contexts for this CPT */
193         struct kfid_ep *end_tx;
194         struct kfid_ep *end_rx;
195
196         /* Corresponding CQs */
197         struct kfilnd_cq *end_tx_cq;
198         struct kfilnd_cq *end_rx_cq;
199
200         /* Specific config values for this endpoint */
201         struct kfilnd_dev *end_dev;
202         int end_cpt;
203         int end_context_id;
204
205         /* List of transactions. */
206         struct list_head tn_list;
207         spinlock_t tn_list_lock;
208
209         /* Replay queues. */
210         struct list_head tn_replay;
211         struct list_head imm_buffer_replay;
212         spinlock_t replay_lock;
213         struct timer_list replay_timer;
214         struct work_struct replay_work;
215         atomic_t replay_count;
216
217         /* Key used to build the tag for tagged buffers. */
218         struct ida keys;
219
220         /* Pre-posted immediate buffers */
221         struct kfilnd_immediate_buffer end_immed_bufs[];
222 };
223
224 struct kfilnd_peer {
225         struct rhash_head kp_node;
226         struct rcu_head kp_rcu_head;
227         struct kfilnd_dev *kp_dev;
228         lnet_nid_t kp_nid;
229         kfi_addr_t kp_addr;
230         atomic_t kp_rx_base;
231         atomic_t kp_remove_peer;
232         refcount_t kp_cnt;
233         time64_t kp_last_alive;
234         u16 kp_version;
235         u32 kp_local_session_key;
236         u32 kp_remote_session_key;
237         atomic_t kp_hello_pending;
238         time64_t kp_hello_ts;
239 };
240
241 static inline bool kfilnd_peer_deleted(struct kfilnd_peer *kp)
242 {
243         return atomic_read(&kp->kp_remove_peer) > 0;
244 }
245
246 /* Sets kp_hello_sending
247  * Returns true if it was already set
248  * Returns false otherwise
249  */
250 static inline bool kfilnd_peer_set_check_hello_pending(struct kfilnd_peer *kp)
251 {
252         return (atomic_cmpxchg(&kp->kp_hello_pending, 0, 1) == 1);
253 }
254
255 static inline void kfilnd_peer_clear_hello_pending(struct kfilnd_peer *kp)
256 {
257         atomic_set(&kp->kp_hello_pending, 0);
258 }
259
260 static inline bool kfilnd_peer_is_new_peer(struct kfilnd_peer *kp)
261 {
262         return kp->kp_version == 0;
263 }
264
265 /* Peer needs hello if it is not up to date and there is not already a hello
266  * in flight.
267  *
268  * If hello was sent more than LND timeout seconds ago, and we never received a
269  * response, then send another one.
270  */
271 static inline bool kfilnd_peer_needs_hello(struct kfilnd_peer *kp)
272 {
273         if (atomic_read(&kp->kp_hello_pending) == 0) {
274                 if (kfilnd_peer_is_new_peer(kp))
275                         return true;
276         } else if (ktime_before(kp->kp_hello_ts + lnet_get_lnd_timeout(),
277                                 ktime_get_seconds())) {
278                 /* Sent hello but never received reply */
279                 CDEBUG(D_NET,
280                        "No response from %s(%p):0x%llx after %lld\n",
281                        libcfs_nid2str(kp->kp_nid), kp, kp->kp_addr,
282                        ktime_sub(ktime_get_seconds(), kp->kp_hello_ts));
283
284                 kfilnd_peer_clear_hello_pending(kp);
285                 return true;
286         }
287
288         return false;
289 }
290
291 struct kfilnd_fab {
292         struct list_head entry;
293         struct list_head dom_list;
294         struct mutex dom_list_lock;
295         struct kfid_fabric *fabric;
296         struct kref cnt;
297 };
298
299 struct kfilnd_dom {
300         struct list_head entry;
301         struct list_head dev_list;
302         spinlock_t lock;
303         struct kfilnd_fab *fab;
304         struct kfid_domain *domain;
305         struct kref cnt;
306 };
307
308 /* Transaction States */
309 enum tn_states {
310         TN_STATE_INVALID,
311
312         /* Shared initiator and target states. */
313         TN_STATE_IDLE,
314         TN_STATE_WAIT_TAG_COMP,
315
316         /* Initiator immediate states. */
317         TN_STATE_IMM_SEND,
318
319         /* Initiator bulk states. */
320         TN_STATE_TAGGED_RECV_POSTED,
321         TN_STATE_SEND_FAILED,
322         TN_STATE_WAIT_COMP,
323         TN_STATE_WAIT_TIMEOUT_COMP,
324         TN_STATE_WAIT_SEND_COMP,
325         TN_STATE_WAIT_TIMEOUT_TAG_COMP,
326         TN_STATE_FAIL,
327
328         /* Target states. */
329         TN_STATE_IMM_RECV,
330         TN_STATE_WAIT_TAG_RMA_COMP,
331
332         /* Invalid max value. */
333         TN_STATE_MAX,
334 };
335
336 /* Base duration state stats. */
337 struct kfilnd_tn_duration_stat {
338         atomic64_t accumulated_duration;
339         atomic_t accumulated_count;
340 };
341
342 /* Transaction state stats group into 22 buckets. Bucket zero corresponds to
343  * LNet message size of 0 bytes and buckets 1 through 21 correspond to LNet
344  * message sizes of 1 to 1048576 bytes increasing by a power of 2. LNet message
345  * sizes are round up to the nearest power of 2.
346  */
347 #define KFILND_DATA_SIZE_BUCKETS 22U
348 #define KFILND_DATA_SIZE_MAX_SIZE (1U << (KFILND_DATA_SIZE_BUCKETS - 2))
349 struct kfilnd_tn_data_size_duration_stats {
350         struct kfilnd_tn_duration_stat data_size[KFILND_DATA_SIZE_BUCKETS];
351 };
352
353 static inline unsigned int kfilnd_msg_len_to_data_size_bucket(size_t size)
354 {
355         u64 bit;
356
357         if (size == 0)
358                 return 0;
359         if (size >= KFILND_DATA_SIZE_MAX_SIZE)
360                 return KFILND_DATA_SIZE_BUCKETS - 1;
361
362         /* Round size up to the nearest power of 2. */
363         bit = fls64(size);
364         if (BIT(bit) < size)
365                 bit++;
366
367         return (unsigned int)bit;
368 }
369
370 /* One data size duraction state bucket for each transaction state. */
371 struct kfilnd_tn_state_data_size_duration_stats {
372         struct kfilnd_tn_data_size_duration_stats state[TN_STATE_MAX];
373 };
374
375 struct kfilnd_dev {
376         struct list_head        kfd_list;       /* chain on kfid_devs */
377         struct lnet_ni          *kfd_ni;
378         enum kfilnd_object_states kfd_state;
379
380         /* KFI LND domain the device is associated with. */
381         struct kfilnd_dom       *dom;
382
383         /* Fields specific to kfabric operation */
384         spinlock_t              kfd_lock;
385         struct kfid_ep          *kfd_sep;
386         struct kfid_av          *kfd_av;
387         struct kfilnd_ep        **kfd_endpoints;
388
389         /* Map of LNet NI CPTs to endpoints. */
390         struct kfilnd_ep        **cpt_to_endpoint;
391
392         /* Hash of LNet NIDs to KFI addresses. */
393         struct rhashtable peer_cache;
394
395         /* Per LNet NI states. */
396         struct kfilnd_tn_state_data_size_duration_stats initiator_state_stats;
397         struct kfilnd_tn_state_data_size_duration_stats target_state_stats;
398         struct kfilnd_tn_data_size_duration_stats initiator_stats;
399         struct kfilnd_tn_data_size_duration_stats target_stats;
400
401         /* Per LNet NI debugfs stats. */
402         struct dentry *dev_dir;
403         struct dentry *initiator_state_stats_file;
404         struct dentry *initiator_stats_file;
405         struct dentry *target_state_stats_file;
406         struct dentry *target_stats_file;
407         struct dentry *reset_stats_file;
408
409         /* Physical NIC address. */
410         unsigned int nic_addr;
411         atomic_t session_keys;
412 };
413
414 /* Invalid checksum value is treated as no checksum. */
415 /* TODO: Module parameter to disable checksum? */
416 #define NO_CHECKSUM 0x0
417
418 /* Hello message header. */
419 struct kfilnd_hello_msg {
420         /* Support kfilnd version. */
421         __u16 version;
422
423         /* Base RX context peer should used. */
424         __u16 rx_base;
425
426         /* Session key used by peer. */
427         __u32 session_key;
428
429         /* RX context count peer can target. */
430         __u16 rx_count;
431 } __packed;
432
433 /* Immediate message header. */
434 struct kfilnd_immed_msg {
435         /* Entire LNet header needed by the destination to match incoming
436          * message.
437          */
438         struct lnet_hdr_nid4    hdr;
439
440         /* Entire LNet message payload. */
441         char payload[0];
442 } __packed;
443
444 /* Bulk request message header. */
445 struct kfilnd_bulk_req_msg {
446         /* Entire LNet header needed by the destination to match incoming
447          * message.
448          */
449         struct lnet_hdr_nid4    hdr;
450
451         /* Specific RX context the target must target to push/pull LNet
452          * payload.
453          */
454         __u32 response_rx;
455
456         /* Memory key needed by the target to push/pull LNet payload. */
457         __u16 key;
458 } __packed;
459
460 /* Kfilnd message. Includes base transport header plus embedded protocol
461  * message.
462  */
463 struct kfilnd_msg {
464         /* Unique kfilnd magic. */
465         __u32 magic;
466
467         /* Version of the kfilnd protocol. */
468         __u16 version;
469
470         /* Specific kfilnd protocol type. */
471         __u8 type;
472
473         /* Unused 8 bits. */
474         __u8 reserved;
475
476         /* Number of bytes in message. */
477         __u16 nob;
478
479         /* Checksum of entire message. 0 is checksum disabled. */
480         __sum16 cksum;
481
482         /* Message LNet source NID. */
483         __u64 srcnid;
484
485         /* Message LNet target NID. */
486         __u64 dstnid;
487
488         /* Embedded protocol headers. Must remain at bottom. */
489         union {
490                 struct kfilnd_immed_msg immed;
491                 struct kfilnd_bulk_req_msg bulk_req;
492                 struct kfilnd_hello_msg hello;
493         } __packed proto;
494 } __packed;
495
496 #define KFILND_MSG_MAGIC LNET_PROTO_KFI_MAGIC   /* unique magic */
497
498 #define KFILND_MSG_VERSION_1    0x1
499 #define KFILND_MSG_VERSION      KFILND_MSG_VERSION_1
500
501 /* Get the KFI RX context from a KFI RX address. RX context information is
502  * stored in the MSBs of the KFI address.
503  */
504 #define KFILND_RX_CONTEXT(addr) ((addr) >> (64 - KFILND_FAB_RX_CTX_BITS))
505
506 #define KFILND_EP_DEBUG(ep, fmt, ...) \
507         CDEBUG(D_NET, "%s:%d " fmt "\n", \
508                libcfs_nidstr(&(ep)->end_dev->kfd_ni->ni_nid), \
509                (ep)->end_context_id, ##__VA_ARGS__)
510
511 #define KFILND_EP_ERROR(ep, fmt, ...) \
512         CNETERR("%s:%d " fmt "\n", \
513                 libcfs_nidstr(&(ep)->end_dev->kfd_ni->ni_nid), \
514                 (ep)->end_context_id, ##__VA_ARGS__)
515
516 #define KFILND_TN_PEER_VALID(tn) \
517         !IS_ERR_OR_NULL((tn)->tn_kp)
518
519 #define KFILND_TN_DIR_DEBUG(tn, fmt, dir, ...) \
520         CDEBUG(D_NET, "%s Transaction ID %p: %s:%u %s %s(%p):0x%llx " fmt "\n", \
521                msg_type_to_str(tn->msg_type), \
522                (tn), \
523                libcfs_nidstr(&(tn)->tn_ep->end_dev->kfd_ni->ni_nid), \
524                (tn)->tn_ep->end_context_id, dir, \
525                libcfs_nid2str((tn)->tn_kp->kp_nid), tn->tn_kp, \
526                KFILND_TN_PEER_VALID(tn) ? \
527                 KFILND_RX_CONTEXT((tn)->tn_kp->kp_addr) : 0, \
528                ##__VA_ARGS__)
529
530 #define KFILND_TN_DEBUG(tn, fmt, ...) \
531         do { \
532                 if ((tn)->is_initiator) \
533                         KFILND_TN_DIR_DEBUG(tn, fmt, "->", ##__VA_ARGS__); \
534                 else \
535                         KFILND_TN_DIR_DEBUG(tn, fmt, "<-", ##__VA_ARGS__); \
536         } while (0)
537
538 #define KFILND_TN_DIR_ERROR(tn, fmt, dir, ...) \
539         CNETERR("Transaction ID %p: %s:%u %s %s(%p):0x%llx " fmt "\n", \
540                 (tn), \
541                 libcfs_nidstr(&(tn)->tn_ep->end_dev->kfd_ni->ni_nid), \
542                 (tn)->tn_ep->end_context_id, dir, \
543                 libcfs_nid2str((tn)->tn_kp->kp_nid), tn->tn_kp, \
544                 KFILND_TN_PEER_VALID(tn) ? \
545                         KFILND_RX_CONTEXT((tn)->tn_kp->kp_addr) : 0, \
546                 ##__VA_ARGS__)
547
548 #define KFILND_TN_ERROR(tn, fmt, ...) \
549         do { \
550                 if ((tn)->is_initiator) \
551                         KFILND_TN_DIR_ERROR(tn, fmt, "->", ##__VA_ARGS__); \
552                 else \
553                         KFILND_TN_DIR_ERROR(tn, fmt, "<-", ##__VA_ARGS__); \
554         } while (0)
555
556 /* TODO: Support NOOPs? */
557 enum kfilnd_msg_type {
558         /* Valid message types start at 1. */
559         KFILND_MSG_INVALID,
560
561         /* Valid message types. */
562         KFILND_MSG_IMMEDIATE,
563         KFILND_MSG_BULK_PUT_REQ,
564         KFILND_MSG_BULK_GET_REQ,
565         KFILND_MSG_HELLO_REQ,
566         KFILND_MSG_HELLO_RSP,
567
568         /* Invalid max value. */
569         KFILND_MSG_MAX,
570 };
571
572 static inline const char *msg_type_to_str(enum kfilnd_msg_type type)
573 {
574         static const char *str[KFILND_MSG_MAX] = {
575                 [KFILND_MSG_INVALID] = "KFILND_MSG_INVALID",
576                 [KFILND_MSG_IMMEDIATE] = "KFILND_MSG_IMMEDIATE",
577                 [KFILND_MSG_BULK_PUT_REQ] = "KFILND_MSG_BULK_PUT_REQ",
578                 [KFILND_MSG_BULK_GET_REQ] = "KFILND_MSG_BULK_GET_REQ",
579                 [KFILND_MSG_HELLO_REQ] = "KFILND_MSG_HELLO_REQ",
580                 [KFILND_MSG_HELLO_RSP] = "KFILND_MSG_HELLO_RSP",
581         };
582
583         if (type >= KFILND_MSG_MAX)
584                 return "KFILND_MSG_INVALID";
585
586         return str[type];
587 };
588
589 static inline const char *tn_state_to_str(enum tn_states type)
590 {
591         static const char *str[TN_STATE_MAX] = {
592                 [TN_STATE_INVALID] = "TN_STATE_INVALID",
593                 [TN_STATE_IDLE] = "TN_STATE_IDLE",
594                 [TN_STATE_WAIT_TAG_COMP] = "TN_STATE_WAIT_TAG_COMP",
595                 [TN_STATE_IMM_SEND] = "TN_STATE_IMM_SEND",
596                 [TN_STATE_TAGGED_RECV_POSTED] = "TN_STATE_TAGGED_RECV_POSTED",
597                 [TN_STATE_SEND_FAILED] = "TN_STATE_SEND_FAILED",
598                 [TN_STATE_WAIT_COMP] = "TN_STATE_WAIT_COMP",
599                 [TN_STATE_WAIT_TIMEOUT_COMP] = "TN_STATE_WAIT_TIMEOUT_COMP",
600                 [TN_STATE_WAIT_SEND_COMP] = "TN_STATE_WAIT_SEND_COMP",
601                 [TN_STATE_WAIT_TIMEOUT_TAG_COMP] = "TN_STATE_WAIT_TIMEOUT_TAG_COMP",
602                 [TN_STATE_FAIL] = "TN_STATE_FAIL",
603                 [TN_STATE_IMM_RECV] = "TN_STATE_IMM_RECV",
604                 [TN_STATE_WAIT_TAG_RMA_COMP] = "TN_STATE_WAIT_TAG_RMA_COMP",
605         };
606
607         return str[type];
608 };
609
610 /* Transaction Events */
611 enum tn_events {
612         TN_EVENT_INVALID,
613
614         /* Initiator events. */
615         TN_EVENT_INIT_IMMEDIATE,
616         TN_EVENT_INIT_BULK,
617         TN_EVENT_TX_HELLO,
618         TN_EVENT_TX_OK,
619         TN_EVENT_TX_FAIL,
620         TN_EVENT_TAG_RX_OK,
621         TN_EVENT_TAG_RX_FAIL,
622         TN_EVENT_TAG_RX_CANCEL,
623         TN_EVENT_TIMEOUT,
624
625         /* Target events. */
626         TN_EVENT_RX_HELLO,
627         TN_EVENT_RX_OK,
628         TN_EVENT_RX_FAIL,
629         TN_EVENT_INIT_TAG_RMA,
630         TN_EVENT_SKIP_TAG_RMA,
631         TN_EVENT_TAG_TX_OK,
632         TN_EVENT_TAG_TX_FAIL,
633
634         /* Invalid max value. */
635         TN_EVENT_MAX,
636 };
637
638 static inline const char *tn_event_to_str(enum tn_events type)
639 {
640         static const char *str[TN_EVENT_MAX] = {
641                 [TN_EVENT_INVALID] = "TN_EVENT_INVALID",
642                 [TN_EVENT_INIT_IMMEDIATE] = "TN_EVENT_INIT_IMMEDIATE",
643                 [TN_EVENT_INIT_BULK] = "TN_EVENT_INIT_BULK",
644                 [TN_EVENT_TX_HELLO] = "TN_EVENT_TX_HELLO",
645                 [TN_EVENT_TX_OK] = "TN_EVENT_TX_OK",
646                 [TN_EVENT_TX_FAIL] = "TN_EVENT_TX_FAIL",
647                 [TN_EVENT_TAG_RX_OK] = "TN_EVENT_TAG_RX_OK",
648                 [TN_EVENT_TAG_RX_FAIL] = "TN_EVENT_TAG_RX_FAIL",
649                 [TN_EVENT_TAG_RX_CANCEL] = "TN_EVENT_TAG_RX_CANCEL",
650                 [TN_EVENT_TIMEOUT] = "TN_EVENT_TIMEOUT",
651                 [TN_EVENT_RX_HELLO] = "TN_EVENT_RX_HELLO",
652                 [TN_EVENT_RX_OK] = "TN_EVENT_RX_OK",
653                 [TN_EVENT_RX_FAIL] = "TN_EVENT_RX_FAIL",
654                 [TN_EVENT_INIT_TAG_RMA] = "TN_EVENT_INIT_TAG_RMA",
655                 [TN_EVENT_SKIP_TAG_RMA] = "TN_EVENT_SKIP_TAG_RMA",
656                 [TN_EVENT_TAG_TX_FAIL] = "TN_EVENT_TAG_TX_FAIL",
657         };
658
659         return str[type];
660 };
661
662 struct kfilnd_transaction_msg {
663         struct kfilnd_msg *msg;
664         size_t length;
665 };
666
667 /* Initiator and target transaction structure. */
668 struct kfilnd_transaction {
669         /* Endpoint list transaction lives on. */
670         struct list_head        tn_entry;
671         struct mutex            tn_lock;        /* to serialize events */
672         int                     tn_status;      /* return code from ops */
673         struct kfilnd_ep        *tn_ep;         /* endpoint we operate under */
674         enum tn_states          tn_state;       /* current state of Tn */
675         struct lnet_msg         *tn_lntmsg;     /* LNet msg to finalize */
676         struct lnet_msg         *tn_getreply;   /* GET LNet msg to finalize */
677
678         bool                    is_initiator;   /* Initiated LNet transfer. */
679
680         /* Transaction send message and target address. */
681         kfi_addr_t              tn_target_addr;
682         struct kfilnd_peer      *tn_kp;
683         struct kfilnd_transaction_msg tn_tx_msg;
684
685         /* Transaction multi-receive buffer and associated receive message. */
686         struct kfilnd_immediate_buffer *tn_posted_buf;
687         struct kfilnd_transaction_msg tn_rx_msg;
688
689         /* LNet buffer used to register a memory region or perform a RMA
690          * operation.
691          */
692         struct bio_vec          tn_kiov[LNET_MAX_IOV];
693         unsigned int            tn_num_iovec;
694
695         /* LNet transaction payload byte count. */
696         unsigned int            tn_nob;
697
698         /* Bulk transaction buffer is sink or source buffer. */
699         bool sink_buffer;
700
701         /* Memory region and remote key used to cover initiator's buffer. */
702         u16                     tn_mr_key;
703
704         /* RX context used to perform response operations to a Put/Get
705          * request. This is required since the request initiator locks in a
706          * transactions to a specific RX context.
707          */
708         u16                     tn_response_mr_key;
709         u8                      tn_response_rx;
710
711         /* Immediate data used to convey transaction state from LNet target to
712          * LNet intiator.
713          */
714         u64 tagged_data;
715
716         /* Bulk operation timeout timer. */
717         struct timer_list timeout_timer;
718         struct work_struct timeout_work;
719
720         /* Transaction health status. */
721         enum lnet_msg_hstatus hstatus;
722
723         /* Transaction deadline. */
724         ktime_t deadline;
725
726         ktime_t tn_alloc_ts;
727         ktime_t tn_state_ts;
728         size_t lnet_msg_len;
729
730         /* Fields used to replay transaction. */
731         struct list_head replay_entry;
732         enum tn_events replay_event;
733         int replay_status;
734
735         enum kfilnd_msg_type msg_type;
736 };
737
738 int kfilnd_send_hello_request(struct kfilnd_dev *dev, int cpt,
739                               struct kfilnd_peer *kp);
740
741 #endif /* _KFILND_ */