/* * Copyright (c) 2013. Intel Corporation. All rights reserved. * Copyright (c) 2006-2012. QLogic Corporation. All rights reserved. * Copyright (c) 2003-2006, PathScale, Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU * General Public License (GPL) Version 2, available from the file * COPYING in the main directory of this source tree, or the * OpenIB.org BSD license below: * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * - Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * - Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #ifndef _PSMI_IN_USER_H #error psm_ep.h not meant to be included directly, include psm_user.h instead #endif #ifndef _PSMI_EP_H #define _PSMI_EP_H #ifdef PSM_HAVE_SCIF #include #endif /* * EPIDs encode the following information: * * LID:16 bits - LID for endpoint * SUBCONTEXT:2 bits - Subcontext used for endpoint * CONTEXT:6 bits - Context used for bits (upto 64 contexts) * IBA_SL: 4 bits - Default SL to use for endpoint * HCATYPE: 4 bits - QLE71XX, QLE72XX, QLE73XX .... */ #define PSMI_HCA_TYPE_UNKNOWN 0 #define PSMI_HCA_TYPE_QLE71XX 1 #define PSMI_HCA_TYPE_QLE72XX 2 #define PSMI_HCA_TYPE_QLE73XX 3 #define PSMI_HCA_TYPE_DEFAULT PSMI_HCA_TYPE_UNKNOWN #define PSMI_SL_DEFAULT 0 #define PSMI_VL_DEFAULT 0 #define PSMI_EPID_PACK_EXT(lid,context,subcontext,hca_type,sl) \ ( ((((uint64_t)lid)&0xffff)<<16) | \ ((((uint64_t)subcontext)&0x3)<<14) | \ ((((uint64_t)context)&0x3f)<<8) | \ ((((uint64_t)sl)&0xf)<<4) | \ (((uint64_t)hca_type)&0xf) ) #define PSMI_EPID_PACK(lid,context,subcontext) \ PSMI_EPID_PACK_EXT(lid,context,subcontext,PSMI_HCA_TYPE_DEFAULT, PSMI_SL_DEFAULT) #define PSMI_EPID_GET_LID(epid) (((epid)>>16)&0xffff) #define PSMI_EPID_GET_SUBCONTEXT(epid) (((epid)>>14)&0x3) #define PSMI_EPID_GET_CONTEXT(epid) (((epid)>>8)&0x3f) #define PSMI_EPID_GET_SL(epid) (((epid)>>4)&0xf) #define PSMI_EPID_GET_HCATYPE(epid) (((epid)>>0)&0xf) #define PSMI_MIN_EP_CONNECT_TIMEOUT (2 * SEC_ULL) #define PSMI_MIN_EP_CLOSE_TIMEOUT (2 * SEC_ULL) #define PSMI_MAX_EP_CLOSE_TIMEOUT (60 * SEC_ULL) #define PSMI_MIN_EP_CLOSE_GRACE_INTERVAL (1 * SEC_ULL) #define PSMI_MAX_EP_CLOSE_GRACE_INTERVAL (10 * SEC_ULL) struct psm_ep { psm_epid_t epid; /**> This endpoint's Endpoint ID */ psm_epaddr_t epaddr; /**> This ep's ep address */ psm_mq_t mq; /**> only 1 MQ */ int unit_id; uint16_t portnum; uint8_t out_sl; uint8_t pad; int did_syslog; psm_uuid_t key; uint16_t network_pkey; /**> InfiniBand Pkey */ uint64_t service_id; /* Infiniband service ID */ psm_path_res_t path_res_type;/* Path resolution for endpoint */ psm_ep_errhandler_t errh; int devid_enabled[PTL_MAX_INIT]; int memmode; /**> min, normal, large memory mode */ #ifdef PSM_HAVE_SCIF scif_epd_t scif_epd; /* scif listen endpoint */ int scif_dma_threshold; /* DMA message size threshold */ int scif_mynodeid; /* my scif node ID */ int scif_nnodes; /* Number of scif nodes on system */ int scif_dma_mode; pthread_t scif_thread; /* Thread listening for SCIF connects */ #endif uint32_t ipath_num_sendbufs; /**> Number of allocated send buffers */ uint32_t ipath_num_descriptors; /** Number of allocated scb descriptors*/ uint32_t ipath_imm_size; /** Immediate data size */ uint32_t shm_mbytes; /**> Number of shared memory pages */ uint32_t connections; /**> Number of connections */ psmi_context_t context; char *context_mylabel; uint32_t yield_spin_cnt; /* EP link-lists */ struct psm_ep *user_ep_next; /* EP link-lists for multi-context. */ struct psm_ep *mctxt_prev; struct psm_ep *mctxt_next; struct psm_ep *mctxt_master; /* Active Message handler table */ void **am_htable; int psmi_kassist_fd; /* when using kassist */ int psmi_kassist_mode; struct amsh_qdirectory *amsh_qdir; uintptr_t amsh_shmbase; /* base for mmap */ uintptr_t amsh_blockbase; /* base for block 0 (after ctl dirpage) */ struct am_ctl_dirpage *amsh_dirpage; psm_uuid_t amsh_keyno; /* context key uuid */ char *amsh_keyname;/* context keyname */ int amsh_shmfd; /* context shared mmap fd */ int amsh_shmidx; /* last used shmidx */ int amsh_max_idx; /* max directory idx seen so far */ uint64_t gid_hi; uint64_t gid_lo; ptl_ctl_t ptl_amsh; ptl_ctl_t ptl_ips; ptl_ctl_t ptl_self; /* All ptl data is allocated inline below */ uint8_t ptl_base_data[0] __attribute__((aligned(8))); }; struct mqq { psm_mq_req_t first; psm_mq_req_t *lastp; }; struct mqsq { psm_mq_req_t first; psm_mq_req_t *lastp; }; typedef union psmi_egrid { struct { uint32_t egr_flowid : 8; uint32_t egr_msgno : 24; }; uint32_t egr_data; } psmi_egrid_t; typedef union psmi_seqnum { struct { uint32_t seq:11; uint32_t gen:8; uint32_t flow:5; }; struct { uint32_t pkt:16; uint32_t msg:8; }; struct { uint32_t psn:24; }; uint32_t val; } psmi_seqnum_t; struct psm_epaddr { struct ptl *ptl; /* Which ptl owns this epaddress */ ptl_ctl_t *ptlctl; /* The control structure for the ptl */ psm_epid_t epid; psm_ep_t ep; void *usr_ep_ctxt; /* User context associated with endpoint */ STAILQ_HEAD(, psm_mq_req) egrlong; /**> egrlong request queue */ STAILQ_HEAD(, psm_mq_req) egrdata; /**> egrlong data queue */ psmi_egrid_t xmit_egrlong; /* PTLs have a few ways to initialize the ptl address */ union { ptl_epaddr_t *ptladdr; uint32_t _ptladdr_u32[2]; uint64_t _ptladdr_u64; uint8_t _ptladdr_data[0]; }; /* it makes sense only in master */ uint64_t mctxt_gidhi[IPATH_MAX_UNIT]; psm_epid_t mctxt_epid[IPATH_MAX_UNIT]; int mctxt_epcount; int mctxt_nsconn; /* # slave connection */ uint16_t mctxt_send_seqnum; uint16_t mctxt_recv_seqnum; struct psm_epaddr *mctxt_current; struct mqsq outoforder_q; /**> OutofOrder queue */ int outoforder_c; /* OOO queue count */ /* epaddr linklist for multi-context. */ struct psm_epaddr *mctxt_master; struct psm_epaddr *mctxt_prev; struct psm_epaddr *mctxt_next; }; #define PSM_MCTXT_APPEND(head, node) \ node->mctxt_prev = head->mctxt_prev; \ node->mctxt_next = head; \ head->mctxt_prev->mctxt_next = node; \ head->mctxt_prev = node; \ node->mctxt_master = head #define PSM_MCTXT_REMOVE(node) \ node->mctxt_prev->mctxt_next = node->mctxt_next; \ node->mctxt_next->mctxt_prev = node->mctxt_prev; \ node->mctxt_next = node->mctxt_prev = node; \ node->mctxt_master = NULL #ifndef PSMI_BLOCKUNTIL_POLLS_BEFORE_YIELD # define PSMI_BLOCKUNTIL_POLLS_BEFORE_YIELD 250 #endif /* * Users of BLOCKUNTIL should check the value of err upon return */ #define PSMI_BLOCKUNTIL(ep,err,cond) do { \ int spin_cnt = 0; \ PSMI_PROFILE_BLOCK(); \ while (!(cond)) { \ err = psmi_poll_internal(ep, 1); \ if (err == PSM_OK_NO_PROGRESS) { \ PSMI_PROFILE_REBLOCK(1); \ if (++spin_cnt == (ep)->yield_spin_cnt) { \ spin_cnt = 0; \ PSMI_PYIELD(); \ } \ } \ else if (err == PSM_OK) { \ PSMI_PROFILE_REBLOCK(0); \ spin_cnt = 0; \ } \ else \ break; \ } \ PSMI_PROFILE_UNBLOCK(); \ } while(0) #endif /* _PSMI_EP_H */