📄 viblnd.c
字号:
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * * Copyright (C) 2004 Cluster File Systems, Inc. * Author: Eric Barton <eric@bartonsoftware.com> * Author: Frank Zago <fzago@systemfabricworks.com> * * This file is part of Lustre, http://www.lustre.org. * * Lustre is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License as published by the Free Software Foundation. * * Lustre is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Lustre; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */#include "viblnd.h"lnd_t the_kiblnd = { .lnd_type = VIBLND, .lnd_startup = kibnal_startup, .lnd_shutdown = kibnal_shutdown, .lnd_ctl = kibnal_ctl, .lnd_send = kibnal_send, .lnd_recv = kibnal_recv, .lnd_eager_recv = kibnal_eager_recv,};kib_data_t kibnal_data;void vibnal_assert_wire_constants (void){ /* Wire protocol assertions generated by 'wirecheck' * running on Linux robert 2.6.11-1.27_FC3 #1 Tue May 17 20:27:37 EDT 2005 i686 athlon i386 G * with gcc version 3.4.3 20050227 (Red Hat 3.4.3-22.fc3) */ /* Constants... */ CLASSERT (IBNAL_MSG_MAGIC == 0x0be91b91); CLASSERT (IBNAL_MSG_VERSION == 0x11); CLASSERT (IBNAL_MSG_CONNREQ == 0xc0); CLASSERT (IBNAL_MSG_CONNACK == 0xc1); CLASSERT (IBNAL_MSG_NOOP == 0xd0); CLASSERT (IBNAL_MSG_IMMEDIATE == 0xd1); CLASSERT (IBNAL_MSG_PUT_REQ == 0xd2); CLASSERT (IBNAL_MSG_PUT_NAK == 0xd3); CLASSERT (IBNAL_MSG_PUT_ACK == 0xd4); CLASSERT (IBNAL_MSG_PUT_DONE == 0xd5); CLASSERT (IBNAL_MSG_GET_REQ == 0xd6); CLASSERT (IBNAL_MSG_GET_DONE == 0xd7); /* Checks for struct kib_connparams_t */ CLASSERT ((int)sizeof(kib_connparams_t) == 12); CLASSERT ((int)offsetof(kib_connparams_t, ibcp_queue_depth) == 0); CLASSERT ((int)sizeof(((kib_connparams_t *)0)->ibcp_queue_depth) == 4); CLASSERT ((int)offsetof(kib_connparams_t, ibcp_max_msg_size) == 4); CLASSERT ((int)sizeof(((kib_connparams_t *)0)->ibcp_max_msg_size) == 4); CLASSERT ((int)offsetof(kib_connparams_t, ibcp_max_frags) == 8); CLASSERT ((int)sizeof(((kib_connparams_t *)0)->ibcp_max_frags) == 4); /* Checks for struct kib_immediate_msg_t */ CLASSERT ((int)sizeof(kib_immediate_msg_t) == 72); CLASSERT ((int)offsetof(kib_immediate_msg_t, ibim_hdr) == 0); CLASSERT ((int)sizeof(((kib_immediate_msg_t *)0)->ibim_hdr) == 72); CLASSERT ((int)offsetof(kib_immediate_msg_t, ibim_payload[13]) == 85); CLASSERT ((int)sizeof(((kib_immediate_msg_t *)0)->ibim_payload[13]) == 1); CLASSERT (IBNAL_USE_FMR == 1); /* Checks for struct kib_rdma_desc_t */ CLASSERT ((int)sizeof(kib_rdma_desc_t) == 16); CLASSERT ((int)offsetof(kib_rdma_desc_t, rd_addr) == 0); CLASSERT ((int)sizeof(((kib_rdma_desc_t *)0)->rd_addr) == 8); CLASSERT ((int)offsetof(kib_rdma_desc_t, rd_nob) == 8); CLASSERT ((int)sizeof(((kib_rdma_desc_t *)0)->rd_nob) == 4); CLASSERT ((int)offsetof(kib_rdma_desc_t, rd_key) == 12); CLASSERT ((int)sizeof(((kib_rdma_desc_t *)0)->rd_key) == 4); /* Checks for struct kib_putreq_msg_t */ CLASSERT ((int)sizeof(kib_putreq_msg_t) == 80); CLASSERT ((int)offsetof(kib_putreq_msg_t, ibprm_hdr) == 0); CLASSERT ((int)sizeof(((kib_putreq_msg_t *)0)->ibprm_hdr) == 72); CLASSERT ((int)offsetof(kib_putreq_msg_t, ibprm_cookie) == 72); CLASSERT ((int)sizeof(((kib_putreq_msg_t *)0)->ibprm_cookie) == 8); /* Checks for struct kib_putack_msg_t */ CLASSERT ((int)sizeof(kib_putack_msg_t) == 32); CLASSERT ((int)offsetof(kib_putack_msg_t, ibpam_src_cookie) == 0); CLASSERT ((int)sizeof(((kib_putack_msg_t *)0)->ibpam_src_cookie) == 8); CLASSERT ((int)offsetof(kib_putack_msg_t, ibpam_dst_cookie) == 8); CLASSERT ((int)sizeof(((kib_putack_msg_t *)0)->ibpam_dst_cookie) == 8); CLASSERT ((int)offsetof(kib_putack_msg_t, ibpam_rd) == 16); CLASSERT ((int)sizeof(((kib_putack_msg_t *)0)->ibpam_rd) == 16); /* Checks for struct kib_get_msg_t */ CLASSERT ((int)sizeof(kib_get_msg_t) == 96); CLASSERT ((int)offsetof(kib_get_msg_t, ibgm_hdr) == 0); CLASSERT ((int)sizeof(((kib_get_msg_t *)0)->ibgm_hdr) == 72); CLASSERT ((int)offsetof(kib_get_msg_t, ibgm_cookie) == 72); CLASSERT ((int)sizeof(((kib_get_msg_t *)0)->ibgm_cookie) == 8); CLASSERT ((int)offsetof(kib_get_msg_t, ibgm_rd) == 80); CLASSERT ((int)sizeof(((kib_get_msg_t *)0)->ibgm_rd) == 16); /* Checks for struct kib_completion_msg_t */ CLASSERT ((int)sizeof(kib_completion_msg_t) == 12); CLASSERT ((int)offsetof(kib_completion_msg_t, ibcm_cookie) == 0); CLASSERT ((int)sizeof(((kib_completion_msg_t *)0)->ibcm_cookie) == 8); CLASSERT ((int)offsetof(kib_completion_msg_t, ibcm_status) == 8); CLASSERT ((int)sizeof(((kib_completion_msg_t *)0)->ibcm_status) == 4); /* Checks for struct kib_msg_t */ CLASSERT ((int)sizeof(kib_msg_t) == 152); CLASSERT ((int)offsetof(kib_msg_t, ibm_magic) == 0); CLASSERT ((int)sizeof(((kib_msg_t *)0)->ibm_magic) == 4); CLASSERT ((int)offsetof(kib_msg_t, ibm_version) == 4); CLASSERT ((int)sizeof(((kib_msg_t *)0)->ibm_version) == 2); CLASSERT ((int)offsetof(kib_msg_t, ibm_type) == 6); CLASSERT ((int)sizeof(((kib_msg_t *)0)->ibm_type) == 1); CLASSERT ((int)offsetof(kib_msg_t, ibm_credits) == 7); CLASSERT ((int)sizeof(((kib_msg_t *)0)->ibm_credits) == 1); CLASSERT ((int)offsetof(kib_msg_t, ibm_nob) == 8); CLASSERT ((int)sizeof(((kib_msg_t *)0)->ibm_nob) == 4); CLASSERT ((int)offsetof(kib_msg_t, ibm_cksum) == 12); CLASSERT ((int)sizeof(((kib_msg_t *)0)->ibm_cksum) == 4); CLASSERT ((int)offsetof(kib_msg_t, ibm_srcnid) == 16); CLASSERT ((int)sizeof(((kib_msg_t *)0)->ibm_srcnid) == 8); CLASSERT ((int)offsetof(kib_msg_t, ibm_srcstamp) == 24); CLASSERT ((int)sizeof(((kib_msg_t *)0)->ibm_srcstamp) == 8); CLASSERT ((int)offsetof(kib_msg_t, ibm_dstnid) == 32); CLASSERT ((int)sizeof(((kib_msg_t *)0)->ibm_dstnid) == 8); CLASSERT ((int)offsetof(kib_msg_t, ibm_dststamp) == 40); CLASSERT ((int)sizeof(((kib_msg_t *)0)->ibm_dststamp) == 8); CLASSERT ((int)offsetof(kib_msg_t, ibm_seq) == 48); CLASSERT ((int)sizeof(((kib_msg_t *)0)->ibm_seq) == 8); CLASSERT ((int)offsetof(kib_msg_t, ibm_u.connparams) == 56); CLASSERT ((int)sizeof(((kib_msg_t *)0)->ibm_u.connparams) == 12); CLASSERT ((int)offsetof(kib_msg_t, ibm_u.immediate) == 56); CLASSERT ((int)sizeof(((kib_msg_t *)0)->ibm_u.immediate) == 72); CLASSERT ((int)offsetof(kib_msg_t, ibm_u.putreq) == 56); CLASSERT ((int)sizeof(((kib_msg_t *)0)->ibm_u.putreq) == 80); CLASSERT ((int)offsetof(kib_msg_t, ibm_u.putack) == 56); CLASSERT ((int)sizeof(((kib_msg_t *)0)->ibm_u.putack) == 32); CLASSERT ((int)offsetof(kib_msg_t, ibm_u.get) == 56); CLASSERT ((int)sizeof(((kib_msg_t *)0)->ibm_u.get) == 96); CLASSERT ((int)offsetof(kib_msg_t, ibm_u.completion) == 56); CLASSERT ((int)sizeof(((kib_msg_t *)0)->ibm_u.completion) == 12);}__u32 kibnal_cksum (void *ptr, int nob){ char *c = ptr; __u32 sum = 0; while (nob-- > 0) sum = ((sum << 1) | (sum >> 31)) + *c++; /* ensure I don't return 0 (== no checksum) */ return (sum == 0) ? 1 : sum;}voidkibnal_init_msg(kib_msg_t *msg, int type, int body_nob){ msg->ibm_type = type; msg->ibm_nob = offsetof(kib_msg_t, ibm_u) + body_nob;}voidkibnal_pack_msg(kib_msg_t *msg, __u32 version, int credits, lnet_nid_t dstnid, __u64 dststamp, __u64 seq){ /* CAVEAT EMPTOR! all message fields not set here should have been * initialised previously. */ msg->ibm_magic = IBNAL_MSG_MAGIC; msg->ibm_version = version; /* ibm_type */ msg->ibm_credits = credits; /* ibm_nob */ msg->ibm_cksum = 0; msg->ibm_srcnid = lnet_ptlcompat_srcnid(kibnal_data.kib_ni->ni_nid, dstnid); msg->ibm_srcstamp = kibnal_data.kib_incarnation; msg->ibm_dstnid = dstnid; msg->ibm_dststamp = dststamp; msg->ibm_seq = seq; if (*kibnal_tunables.kib_cksum) { /* NB ibm_cksum zero while computing cksum */ msg->ibm_cksum = kibnal_cksum(msg, msg->ibm_nob); }}intkibnal_unpack_msg(kib_msg_t *msg, __u32 expected_version, int nob){ const int hdr_size = offsetof(kib_msg_t, ibm_u); __u32 msg_cksum; __u32 msg_version; int flip; int msg_nob;#if !IBNAL_USE_FMR int i; int n;#endif /* 6 bytes are enough to have received magic + version */ if (nob < 6) { CERROR("Short message: %d\n", nob); return -EPROTO; } /* Future protocol version compatibility support! * If the viblnd-specific protocol changes, or when LNET unifies * protocols over all LNDs, the initial connection will negotiate a * protocol version. If I find this, I avoid any console errors. If * my is doing connection establishment, the reject will tell the peer * which version I'm running. */ if (msg->ibm_magic == IBNAL_MSG_MAGIC) { flip = 0; } else if (msg->ibm_magic == __swab32(IBNAL_MSG_MAGIC)) { flip = 1; } else { if (msg->ibm_magic == LNET_PROTO_MAGIC || msg->ibm_magic == __swab32(LNET_PROTO_MAGIC)) return -EPROTO; /* Completely out to lunch */ CERROR("Bad magic: %08x\n", msg->ibm_magic); return -EPROTO; } msg_version = flip ? __swab16(msg->ibm_version) : msg->ibm_version; if (expected_version == 0) { if (msg_version != IBNAL_MSG_VERSION_RDMAREPLYNOTRSRVD && msg_version != IBNAL_MSG_VERSION) return -EPROTO; } else if (msg_version != expected_version) { CERROR("Bad version: %x(%x expected)\n", msg_version, expected_version); return -EPROTO; } if (nob < hdr_size) { CERROR("Short message: %d\n", nob); return -EPROTO; } msg_nob = flip ? __swab32(msg->ibm_nob) : msg->ibm_nob; if (msg_nob > nob) { CERROR("Short message: got %d, wanted %d\n", nob, msg_nob); return -EPROTO; } /* checksum must be computed with ibm_cksum zero and BEFORE anything * gets flipped */ msg_cksum = flip ? __swab32(msg->ibm_cksum) : msg->ibm_cksum; msg->ibm_cksum = 0; if (msg_cksum != 0 && msg_cksum != kibnal_cksum(msg, msg_nob)) { CERROR("Bad checksum\n"); return -EPROTO; } msg->ibm_cksum = msg_cksum; if (flip) { /* leave magic unflipped as a clue to peer endianness */ msg->ibm_version = msg_version; CLASSERT (sizeof(msg->ibm_type) == 1); CLASSERT (sizeof(msg->ibm_credits) == 1); msg->ibm_nob = msg_nob; __swab64s(&msg->ibm_srcnid); __swab64s(&msg->ibm_srcstamp); __swab64s(&msg->ibm_dstnid); __swab64s(&msg->ibm_dststamp); __swab64s(&msg->ibm_seq); } if (msg->ibm_srcnid == LNET_NID_ANY) { CERROR("Bad src nid: %s\n", libcfs_nid2str(msg->ibm_srcnid)); return -EPROTO; } switch (msg->ibm_type) { default: CERROR("Unknown message type %x\n", msg->ibm_type); return -EPROTO; case IBNAL_MSG_NOOP: break; case IBNAL_MSG_IMMEDIATE: if (msg_nob < offsetof(kib_msg_t, ibm_u.immediate.ibim_payload[0])) { CERROR("Short IMMEDIATE: %d(%d)\n", msg_nob, (int)offsetof(kib_msg_t, ibm_u.immediate.ibim_payload[0])); return -EPROTO; } break; case IBNAL_MSG_PUT_REQ: if (msg_nob < hdr_size + sizeof(msg->ibm_u.putreq)) { CERROR("Short PUT_REQ: %d(%d)\n", msg_nob, (int)(hdr_size + sizeof(msg->ibm_u.putreq))); return -EPROTO; } break; case IBNAL_MSG_PUT_ACK: if (msg_nob < hdr_size + sizeof(msg->ibm_u.putack)) { CERROR("Short PUT_ACK: %d(%d)\n", msg_nob, (int)(hdr_size + sizeof(msg->ibm_u.putack))); return -EPROTO; }#if IBNAL_USE_FMR if (flip) { __swab64s(&msg->ibm_u.putack.ibpam_rd.rd_addr); __swab32s(&msg->ibm_u.putack.ibpam_rd.rd_nob); __swab32s(&msg->ibm_u.putack.ibpam_rd.rd_key); }#else if (flip) { __swab32s(&msg->ibm_u.putack.ibpam_rd.rd_key); __swab32s(&msg->ibm_u.putack.ibpam_rd.rd_nfrag); } n = msg->ibm_u.putack.ibpam_rd.rd_nfrag; if (n <= 0 || n > IBNAL_MAX_RDMA_FRAGS) { CERROR("Bad PUT_ACK nfrags: %d, should be 0 < n <= %d\n", n, IBNAL_MAX_RDMA_FRAGS); return -EPROTO; } if (msg_nob < offsetof(kib_msg_t, ibm_u.putack.ibpam_rd.rd_frags[n])) { CERROR("Short PUT_ACK: %d(%d)\n", msg_nob, (int)offsetof(kib_msg_t, ibm_u.putack.ibpam_rd.rd_frags[n])); return -EPROTO; } if (flip) { for (i = 0; i < n; i++) { __swab32s(&msg->ibm_u.putack.ibpam_rd.rd_frags[i].rf_nob); __swab32s(&msg->ibm_u.putack.ibpam_rd.rd_frags[i].rf_addr_lo); __swab32s(&msg->ibm_u.putack.ibpam_rd.rd_frags[i].rf_addr_hi); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -