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