📄 ibu.c
字号:
/* -*- Mode: C; c-basic-offset:4 ; -*- *//* * (C) 2001 by Argonne National Laboratory. * See COPYRIGHT in top-level directory. *//*#include <winsock2.h>#include <windows.h>*/#include "ibimpl.h"#include "ibu.h"#include "iba.h"#include "psc_iba.h"#include "blockallocator.h"#include <stdio.h>typedef union ibu_work_id_handle_t{ ib_uint64_t id; struct ibu_data { ib_uint32_t ptr, mem; } data;} ibu_work_id_handle_t;typedef int IBU_STATE;#define IBU_ACCEPTING 0x0001#define IBU_ACCEPTED 0x0002#define IBU_CONNECTING 0x0004#define IBU_READING 0x0008#define IBU_WRITING 0x0010typedef struct ibu_buffer{ int use_iov; DWORD num_bytes; void *buffer; int bufflen; IBU_IOV iov[IBU_IOV_MAXLEN]; int iovlen; int index; int total; int (*progress_update)(int,void*);} ibu_buffer;typedef struct ibu_state_t{ IBU_STATE state; ib_uint32_t lkey; ib_qp_handle_t qp_handle; BlockAllocator allocator; ib_uint32_t mtu_size; ib_uint32_t dlid; ib_mr_handle_t mr_handle; ib_uint32_t dest_qp_num; int closing; int pending_operations; /* read and write structures */ ibu_buffer read; ibu_buffer write; /* user pointer */ void *user_ptr;} ibu_state_t;#define IBU_ERROR_MSG_LENGTH 255#define IBU_PACKET_SIZE (1024 * 64)#define IBU_PACKET_COUNT 64#define IBU_NUM_PREPOSTED_RECEIVES 32#define IBU_MAX_CQ_ENTRIES 255typedef struct IBU_Global { ib_hca_handle_t hca_handle; ib_pd_handle_t pd_handle; ib_cqd_handle_t cqd_handle; int lid; ib_hca_attr_t * attr_p; int error; char err_msg[IBU_ERROR_MSG_LENGTH];} IBU_Global;extern IBU_Global IBU_Process;#define DEFAULT_NUM_RETRIES 10static int g_connection_attempts = DEFAULT_NUM_RETRIES;static int g_num_cp_threads = 2;/* utility allocator functions */typedef struct BlockAllocator_struct * BlockAllocator;BlockAllocator BlockAllocInit(unsigned int blocksize, int count, int incrementsize, void *(* alloc_fn)(unsigned int size), void (* free_fn)(void *p));int BlockAllocFinalize(BlockAllocator *p);void * BlockAlloc(BlockAllocator p);int BlockFree(BlockAllocator p, void *pBlock);struct BlockAllocator_struct{ void **pNextFree; void *(* alloc_fn)(size_t size); void (* free_fn)(void *p); struct BlockAllocator_struct *pNextAllocation; unsigned int nBlockSize; int nCount, nIncrementSize;#ifdef WITH_ALLOCATOR_LOCKING MPIDU_Lock_t lock;#endif};static int g_nLockSpinCount = 100;#ifdef WITH_ALLOCATOR_LOCKINGtypedef volatile long MPIDU_Lock_t;#include <errno.h>#ifdef HAVE_WINDOWS_H#include <winsock2.h>#include <windows.h>#endifstatic inline void MPIDU_Init_lock( MPIDU_Lock_t *lock ){ *(lock) = 0;}static inline void MPIDU_Lock( MPIDU_Lock_t *lock ){ int i; for (;;) { for (i=0; i<g_nLockSpinCount; i++) { if (*lock == 0) {#ifdef HAVE_INTERLOCKEDEXCHANGE if (InterlockedExchange((LPLONG)lock, 1) == 0) { /*printf("lock %x\n", lock);fflush(stdout);*/ MPID_PROFILE_OUT(MPIDU_BUSY_LOCK); return; }#elif defined(HAVE_COMPARE_AND_SWAP) if (compare_and_swap(lock, 0, 1) == 1) { MPID_PROFILE_OUT(MPIDU_BUSY_LOCK); return; }#else#error Atomic memory operation needed to implement busy locks#endif } } MPIDU_Yield(); }}static inline void MPIDU_Unlock( MPIDU_Lock_t *lock ){ *(lock) = 0;}static inline void MPIDU_Busy_wait( MPIDU_Lock_t *lock ){ int i; for (;;) { for (i=0; i<g_nLockSpinCount; i++) if (!*lock) { return; } MPIDU_Yield(); }}static inline void MPIDU_Free_lock( MPIDU_Lock_t *lock ){}/*@ MPIDU_Compare_swap - Parameters:+ void **dest. void *new_val. void *compare_val. MPIDU_Lock_t *lock- void **original_val Notes:@*/static inline int MPIDU_Compare_swap( void **dest, void *new_val, void *compare_val, MPIDU_Lock_t *lock, void **original_val ){ /* dest = pointer to value to be checked (address size) new_val = value to set dest to if *dest == compare_val original_val = value of dest prior to this operation */#ifdef HAVE_NT_LOCKS /* *original_val = (void*)InterlockedCompareExchange(dest, new_val, compare_val); */ *original_val = InterlockedCompareExchangePointer(dest, new_val, compare_val);#elif defined(HAVE_COMPARE_AND_SWAP) if (compare_and_swap((volatile long *)dest, (long)compare_val, (long)new_val)) *original_val = new_val;#else#error Locking functions not defined#endif return 0;}#endif /* WITH_ALLOCATOR_LOCKING */static BlockAllocator BlockAllocInit(unsigned int blocksize, int count, int incrementsize, void *(* alloc_fn)(unsigned int size), void (* free_fn)(void *p)){ BlockAllocator p; void **ppVoid; int i; p = alloc_fn( sizeof(struct BlockAllocator_struct) + ((blocksize + sizeof(void**)) * count) ); p->alloc_fn = alloc_fn; p->free_fn = free_fn; p->nIncrementSize = incrementsize; p->pNextAllocation = NULL; p->nCount = count; p->nBlockSize = blocksize; p->pNextFree = (void**)(p + 1);#ifdef WITH_ALLOCATOR_LOCKING MPIDU_Init_lock(&p->lock);#endif ppVoid = (void**)(p + 1); for (i=0; i<count-1; i++) { *ppVoid = (void*)((char*)ppVoid + sizeof(void**) + blocksize); ppVoid = *ppVoid; } *ppVoid = NULL; return p;}static int BlockAllocFinalize(BlockAllocator *p){ if (*p == NULL) return 0; BlockAllocFinalize(&(*p)->pNextAllocation); if ((*p)->free_fn != NULL) (*p)->free_fn(*p); *p = NULL; return 0;}static void * BlockAlloc(BlockAllocator p){ void *pVoid; #ifdef WITH_ALLOCATOR_LOCKING MPIDU_Lock(&p->lock);#endif pVoid = p->pNextFree + 1; if (*(p->pNextFree) == NULL) { BlockAllocator pIter = p; while (pIter->pNextAllocation != NULL) pIter = pIter->pNextAllocation; pIter->pNextAllocation = BlockAllocInit(p->nBlockSize, p->nIncrementSize, p->nIncrementSize, p->alloc_fn, p->free_fn); p->pNextFree = pIter->pNextFree; } else p->pNextFree = *(p->pNextFree);#ifdef WITH_ALLOCATOR_LOCKING MPIDU_Unlock(&p->lock);#endif return pVoid;}static int BlockFree(BlockAllocator p, void *pBlock){#ifdef WITH_ALLOCATOR_LOCKING MPIDU_Lock(&p->lock);#endif ((void**)pBlock)--; *((void**)pBlock) = p->pNextFree; p->pNextFree = pBlock;#ifdef WITH_ALLOCATOR_LOCKING MPIDU_Unlock(&p->lock);#endif return 0;}/* utility ibu functions */static ib_uint32_t modifyQP( ibu_t ibu, Ib_qp_state qp_state ){ ib_uint32_t status; ib_qp_attr_list_t attrList; ib_address_vector_t av; attr_rec_t *attr_rec = NULL; if (qp_state == IB_QP_STATE_INIT) { if ((attr_rec = (attr_rec_t *) malloc(sizeof (attr_rec_t) * 5)) == NULL ) { printf("Malloc failed %d\n", __LINE__); return IBU_FAIL; } ((attr_rec[0]).id) = IB_QP_ATTR_PRIMARY_PORT; ((attr_rec[0]).data) = 1; ((attr_rec[1]).id) = IB_QP_ATTR_PRIMARY_P_KEY_IX; ((attr_rec[1]).data) = 0; ((attr_rec[2]).id) = IB_QP_ATTR_RDMA_W_F; ((attr_rec[2]).data) = 1; ((attr_rec[3]).id) = IB_QP_ATTR_RDMA_R_F; ((attr_rec[3]).data) = 1; ((attr_rec[4]).id) = IB_QP_ATTR_ATOMIC_F; ((attr_rec[4]).data) = 0; attrList.attr_num = 5; attrList.attr_rec_p = &attr_rec[0]; } else if (qp_state == IB_QP_STATE_RTR) { av.sl = 0; /*printf("setting dest_lid to ibu->dlid: %d\n", ibu->dlid);*/ av.dest_lid = (ib_uint16_t)ibu->dlid; av.grh_f = 0; av.path_bits = 0; av.max_static_rate = 1; av.global.flow_label = 1; av.global.hop_limit = 1; av.global.src_gid_index = 0; av.global.traffic_class = 1; if ((attr_rec = (attr_rec_t *) malloc(sizeof (attr_rec_t) * 6)) == NULL ) { printf("Malloc failed %d\n", __LINE__); return IBU_FAIL; } ((attr_rec[0]).id) = IB_QP_ATTR_PRIMARY_ADDR; ((attr_rec[0]).data) = (int)&av; ((attr_rec[1]).id) = IB_QP_ATTR_DEST_QPN; ((attr_rec[1]).data) = ibu->dest_qp_num; ((attr_rec[2]).id) = IB_QP_ATTR_RCV_PSN; ((attr_rec[2]).data) = 0; ((attr_rec[3]).id) = IB_QP_ATTR_MTU; ((attr_rec[3]).data) = ibu->mtu_size; ((attr_rec[4]).id) = IB_QP_ATTR_RDMA_READ_LIMIT; ((attr_rec[4]).data) = 4; ((attr_rec[5]).id) = IB_QP_ATTR_RNR_NAK_TIMER; ((attr_rec[5]).data) = 1; attrList.attr_num = 6; attrList.attr_rec_p = &attr_rec[0]; } else if (qp_state == IB_QP_STATE_RTS) { if ((attr_rec = (attr_rec_t *) malloc(sizeof (attr_rec_t) * 5)) == NULL ) { printf("Malloc failed %d\n", __LINE__); return IBU_FAIL; } ((attr_rec[0]).id) = IB_QP_ATTR_SEND_PSN; ((attr_rec[0]).data) = 0; ((attr_rec[1]).id) = IB_QP_ATTR_TIMEOUT; ((attr_rec[1]).data) = 0x7c; ((attr_rec[2]).id) = IB_QP_ATTR_RETRY_COUNT; ((attr_rec[2]).data) = 2048; ((attr_rec[3]).id) = IB_QP_ATTR_RNR_RETRY_COUNT; ((attr_rec[3]).data) = 2048; ((attr_rec[4]).id) = IB_QP_ATTR_DEST_RDMA_READ_LIMIT; ((attr_rec[4]).data) = 4; attrList.attr_num = 5; attrList.attr_rec_p = &attr_rec[0]; } else if (qp_state == IB_QP_STATE_RESET) { attrList.attr_num = 0; attrList.attr_rec_p = NULL; } else { return IBU_FAIL; } status = ib_qp_modify_us(IBU_Process.hca_handle, ibu->qp_handle, qp_state, &attrList ); if (attr_rec) free(attr_rec); if( status != IBU_SUCCESS ) { return status; } return IBU_SUCCESS;}static ib_uint32_t createQP(ibu_t ibu, ibu_set_t set){ ib_uint32_t status; ib_qp_attr_list_t attrList; attr_rec_t attr_rec[] = { {IB_QP_ATTR_SERVICE_TYPE, IB_ST_RELIABLE_CONNECTION}, {IB_QP_ATTR_SEND_CQ, 0}, {IB_QP_ATTR_RCV_CQ, 0}, {IB_QP_ATTR_SEND_REQ_MAX, 0}, {IB_QP_ATTR_RCV_REQ_MAX, 0}, {IB_QP_ATTR_SEND_SGE_MAX, 8}, {IB_QP_ATTR_RCV_SGE_MAX, 8}, {IB_QP_ATTR_SIGNALING_TYPE, QP_SIGNAL_ALL} };
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -