diff --git a/arch/x86/mm/page.c b/arch/x86/mm/page.c index 01b08d1f3..071bbe166 100644 --- a/arch/x86/mm/page.c +++ b/arch/x86/mm/page.c @@ -153,23 +153,23 @@ size_t phys_to_virt(size_t phy) /* LOG_INFO("Fourth for.\n"); */ if (pgt[l] & PG_PRESENT) { // Valid page table entry - /* LOG_INFO("p"); */ + /* LOG_INFO("\tp\n"); */ if ((pgt[l] & PFN_MASK) == pfn) { // Page frame found - LOG_INFO("SAME PAGE.\n"); + LOG_INFO("\tSAME PAGE.\n"); /* LOG_INFO("i: Hex: %zx, Dec: %zd\n", i, i); */ /* LOG_INFO("j: Hex: %zx, Dec: %zd\n", j, j); */ /* LOG_INFO("k: Hex: %zx, Dec: %zd\n", k, k); */ /* LOG_INFO("l: Hex: %zx, Dec: %zd\n", l, l); */ size_t vpn = ((((((i << PAGE_MAP_BITS) | j) << PAGE_MAP_BITS) | k) << PAGE_MAP_BITS) | l) << PAGE_BITS; - /* LOG_INFO("vpn: Hex: %zx, Dec: %zd\n", vpn, vpn); */ + LOG_INFO("\tvpn: Hex: %zx, Dec: %zd\n", vpn, vpn); size_t sext = i & (1UL << (PAGE_MAP_BITS - 1)); - /* LOG_INFO("sext: Hex: %zx, Dec: %zd\n", sext, sext); */ + LOG_INFO("\tsext: Hex: %zx, Dec: %zd\n", sext, sext); if (sext) { - /* LOG_INFO("sext true"); */ + LOG_INFO("\tsext true"); vpn |= ~0UL << VIRT_BITS; - /* LOG_INFO("vpn: Hex: %zx, Dec: %zd\n", vpn, vpn); */ + LOG_INFO("\tvpn: Hex: %zx, Dec: %zd\n", vpn, vpn); } - /* LOG_INFO("return: Hex: %zx, Dec: %zd\n", vpn | off, vpn | off); */ + LOG_INFO("\treturn: Hex: %zx, Dec: %zd\n", vpn | off, vpn | off); return vpn | off; } } diff --git a/include/hermit/ibv_guest_host.h b/include/hermit/ibv_guest_host.h index 269e1fa1e..294c96eb3 100644 --- a/include/hermit/ibv_guest_host.h +++ b/include/hermit/ibv_guest_host.h @@ -45,25 +45,25 @@ inline size_t host_to_guest(size_t address) { } -struct ibv_device * guest_to_host_ibv_device(struct ibv_device * device); -struct ibv_context * guest_to_host_ibv_context(struct ibv_context * context); -struct ibv_context_ops * guest_to_host_ibv_context_ops(struct ibv_context_ops * context_ops); -struct ibv_port_attr * guest_to_host_ibv_port_attr(struct ibv_port_attr * port_attr); +// struct ibv_device * guest_to_host_ibv_device(struct ibv_device * device); +// struct ibv_context * guest_to_host_ibv_context(struct ibv_context * context); +// struct ibv_context_ops * guest_to_host_ibv_context_ops(struct ibv_context_ops * context_ops); +// struct ibv_port_attr * guest_to_host_ibv_port_attr(struct ibv_port_attr * port_attr); struct ibv_recv_wr * guest_to_host_ibv_recv_wr(struct ibv_recv_wr * wr); struct ibv_send_wr * guest_to_host_ibv_send_wr(struct ibv_send_wr * wr); struct ibv_sge * guest_to_host_ibv_sge(struct ibv_sge * sg); -struct ibv_abi_compat_v2 * guest_to_host_ibv_abi_compat_v2(struct ibv_abi_compat_v2 * abi_compat); -pthread_mutex_t * guest_to_host_pthread_mutex_t(pthread_mutex_t * mutex); +// struct ibv_abi_compat_v2 * guest_to_host_ibv_abi_compat_v2(struct ibv_abi_compat_v2 * abi_compat); +// pthread_mutex_t * guest_to_host_pthread_mutex_t(pthread_mutex_t * mutex); -struct ibv_device * host_to_guest_ibv_device(struct ibv_device * device, addr_type type); -struct ibv_context * host_to_guest_ibv_context(struct ibv_context * context, addr_type type); -struct ibv_context_ops * host_to_guest_ibv_context_ops(struct ibv_context_ops * context_ops, addr_type type); -struct ibv_port_attr * host_to_guest_ibv_port_attr(struct ibv_port_attr * port_attr, addr_type type); -struct ibv_comp_channel * host_to_guest_ibv_comp_channel(struct ibv_comp_channel * channel, addr_type type); +// struct ibv_device * host_to_guest_ibv_device(struct ibv_device * device, addr_type type); +// struct ibv_context * host_to_guest_ibv_context(struct ibv_context * context, addr_type type); +// struct ibv_context_ops * host_to_guest_ibv_context_ops(struct ibv_context_ops * context_ops, addr_type type); +// struct ibv_port_attr * host_to_guest_ibv_port_attr(struct ibv_port_attr * port_attr, addr_type type); +// struct ibv_comp_channel * host_to_guest_ibv_comp_channel(struct ibv_comp_channel * channel, addr_type type); struct ibv_recv_wr * host_to_guest_ibv_recv_wr(struct ibv_recv_wr * wr, addr_type type); struct ibv_send_wr * host_to_guest_ibv_send_wr(struct ibv_send_wr * wr, addr_type type); struct ibv_sge * host_to_guest_ibv_sge(struct ibv_sge * sg, addr_type type); -struct ibv_abi_compat_v2 * host_to_guest_ibv_abi_compat_v2(struct ibv_abi_compat_v2 * abi_compat, addr_type type); -pthread_mutex_t * host_to_guest_pthread_mutex_t(pthread_mutex_t * mutex, addr_type type); +// struct ibv_abi_compat_v2 * host_to_guest_ibv_abi_compat_v2(struct ibv_abi_compat_v2 * abi_compat, addr_type type); +// pthread_mutex_t * host_to_guest_pthread_mutex_t(pthread_mutex_t * mutex, addr_type type); #endif // __IBV_GUEST_HOST_H__ diff --git a/kernel/ibv.c b/kernel/ibv.c index 98082388c..2510fd5ef 100644 --- a/kernel/ibv.c +++ b/kernel/ibv.c @@ -1244,6 +1244,7 @@ typedef struct { int ibv_modify_qp(struct ibv_qp * qp, struct ibv_qp_attr * attr, int attr_mask) { uhyve_ibv_modify_qp_t uhyve_args; + uhyve_args.qp = qp; uhyve_args.attr = (struct ibv_qp_attr *) guest_to_host((size_t) attr); // ! uhyve_args.attr_mask = attr_mask; @@ -1344,7 +1345,7 @@ typedef struct { } __attribute__((packed)) uhyve_ibv_post_recv_t; int ibv_post_recv(struct ibv_qp * qp, struct ibv_recv_wr * wr, struct ibv_recv_wr ** bad_wr) { - /* LOG_INFO("KERNEL: ibv_post_recv()\n"); */ + LOG_INFO("KERNEL: ibv_post_recv()\n"); uhyve_ibv_post_recv_t uhyve_args; uhyve_args.qp = qp; @@ -1353,8 +1354,8 @@ int ibv_post_recv(struct ibv_qp * qp, struct ibv_recv_wr * wr, struct ibv_recv_w uhyve_send(UHYVE_PORT_IBV_POST_RECV, (unsigned) virt_to_phys((size_t) &uhyve_args)); - /* host_to_guest_ibv_recv_wr(wr, GUEST); */ // TODO: add this back in - /* LOG_INFO("KERNEL: ibv_post_recv()\n"); */ + /* LOG_INFO("KERNEL: Before host_to_guest_ibv_recv_wr(wr, GUEST);\n"); */ + /* host_to_guest_ibv_recv_wr(wr, GUEST); // TODO: add this back in */ // TODO: Do we want to convert bad_wr's content back to guest memory? diff --git a/kernel/ibv_guest_host.c b/kernel/ibv_guest_host.c index c45a735d6..915fd7a6d 100644 --- a/kernel/ibv_guest_host.c +++ b/kernel/ibv_guest_host.c @@ -37,90 +37,6 @@ #include -/* - * struct ibv_device - */ - -struct ibv_device * guest_to_host_ibv_device(struct ibv_device * device) { - // _ops obsolete. - return (struct ibv_device *) guest_to_host((size_t) device); -} - -struct ibv_device * host_to_guest_ibv_device(struct ibv_device * device, addr_type type) { - struct ibv_device * vaddr = (type == GUEST) ? device - : (struct ibv_device *) host_to_guest((size_t) device); - - return vaddr; -} - - -/* - * struct ibv_context - */ - -struct ibv_context * guest_to_host_ibv_context(struct ibv_context * context) { - context->device = guest_to_host_ibv_device(context->device); - context->abi_compat = guest_to_host_ibv_abi_compat_v2(context->abi_compat); - - guest_to_host_ibv_context_ops(&context->ops); - guest_to_host_pthread_mutex_t(&context->mutex); // TODO - - return (struct ibv_context *) guest_to_host((size_t) context); -} - -struct ibv_context * host_to_guest_ibv_context(struct ibv_context * context, addr_type type) { - struct ibv_context * vaddr = (type == GUEST) ? context - : (struct ibv_context *) host_to_guest((size_t) context); - - vaddr->device = host_to_guest_ibv_device(vaddr->device, HOST); - vaddr->abi_compat = host_to_guest_ibv_abi_compat_v2(vaddr->abi_compat, HOST); - - host_to_guest_ibv_context_ops(&vaddr->ops, GUEST); - host_to_guest_pthread_mutex_t(&vaddr->mutex, GUEST); - - return vaddr; -} - - -/* - * struct ibv_port_attr - */ - -struct ibv_port_attr * guest_to_host_ibv_port_attr(struct ibv_port_attr * port_attr) { - return (struct ibv_port_attr *) guest_to_host((size_t) port_attr); -} - -struct ibv_port_attr * host_to_guest_ibv_port_attr(struct ibv_port_attr * port_attr, addr_type type) { - struct ibv_port_attr * vaddr = (type == GUEST) ? port_attr - : (struct ibv_port_attr *) host_to_guest((size_t) port_attr); - - return vaddr; -} - - -/* - * struct ibv_sge - */ - -struct ibv_sge * guest_to_host_ibv_sge(struct ibv_sge * sg) { - /* LOG_INFO("Entered guest_to_host_ibv_recv_wr()\n"); */ - /* LOG_INFO("\tsg->addr before conversion: %lu\n", sg->addr); */ - sg->addr = (uint64_t) guest_to_host((size_t) sg->addr); - /* LOG_INFO("\tsg->addr after conversion: %lu\n", sg->addr); */ - - return (struct ibv_sge *) guest_to_host((size_t) sg); -} - -struct ibv_sge * host_to_guest_ibv_sge(struct ibv_sge * sg, addr_type type) { - /* LOG_INFO("Entered host_to_guest_ibv_recv_wr()\n"); */ - struct ibv_sge * vaddr = (type == GUEST) ? sg - : (struct ibv_sge *) host_to_guest((size_t) sg); - - vaddr->addr = (uint64_t) host_to_guest((size_t) vaddr->addr); - - return vaddr; -} - // struct ibv_recv_wr { // uint64_t wr_id; // struct ibv_recv_wr *next; @@ -135,43 +51,68 @@ struct ibv_sge * host_to_guest_ibv_sge(struct ibv_sge * sg, addr_type type) { // }; +/* + * struct ibv_sge + */ + +struct ibv_sge * guest_to_host_ibv_sge(struct ibv_sge * sg) { + LOG_INFO("\tEntered guest_to_host_ibv_sge()\n"); + /* LOG_INFO("\tsg->addr before conversion: %lu\n", sg->addr); */ + sg->addr = (uint64_t) guest_to_host((size_t) sg->addr); + /* LOG_INFO("\tsg->addr after conversion: %lu\n", sg->addr); */ + + return (struct ibv_sge *) guest_to_host((size_t) sg); +} + +struct ibv_sge * host_to_guest_ibv_sge(struct ibv_sge * sg, addr_type type) { + LOG_INFO("Entered host_to_guest_ibv_recv_wr()\n"); + struct ibv_sge * vaddr = (type == GUEST) ? sg + : (struct ibv_sge *) host_to_guest((size_t) sg); + + vaddr->addr = (uint64_t) host_to_guest((size_t) vaddr->addr); + + return vaddr; +} + + /* * struct ibv_recv_wr */ struct ibv_recv_wr * guest_to_host_ibv_recv_wr(struct ibv_recv_wr * wr) { - /* LOG_INFO("Entered guest_to_host_ibv_recv_wr()\n"); */ + LOG_INFO("Entered guest_to_host_ibv_recv_wr()\n"); if (wr->next) { - /* LOG_INFO("\twr->next is not NULL\n"); */ + LOG_INFO("\twr->next is not NULL\n"); wr->next = guest_to_host_ibv_recv_wr(wr->next); // linked list } for (int i = 0; i < wr->num_sge; i++) { guest_to_host_ibv_sge(wr->sg_list + i); } + LOG_INFO("\twr->sg_list before conversion, guest: %lu\n", wr->sg_list); wr->sg_list = (struct ibv_sge *) guest_to_host((size_t) wr->sg_list); + LOG_INFO("\twr->sg_list after conversion, host: %lu\n", wr->sg_list); return (struct ibv_recv_wr *) guest_to_host((size_t) wr); } struct ibv_recv_wr * host_to_guest_ibv_recv_wr(struct ibv_recv_wr * wr, addr_type type) { - /* LOG_INFO("Entered host_to_guest_ibv_recv_wr()\n"); */ + LOG_INFO("Entered host_to_guest_ibv_recv_wr()\n"); struct ibv_recv_wr * vaddr = (type == GUEST) ? wr : (struct ibv_recv_wr *) host_to_guest((size_t) wr); + LOG_INFO("\tvaddr set.\n"); if (vaddr->next) { - /* LOG_INFO("\twr->next is not NULL\n"); */ + LOG_INFO("\twr->next is not NULL\n"); vaddr->next = host_to_guest_ibv_recv_wr(vaddr->next, HOST); // linked list } - vaddr->sg_list = (struct ibv_sge *) host_to_guest((size_t) vaddr->sg_list); + LOG_INFO("\twr->sg_list before conversion, host: %lu\n", vaddr->sg_list); + vaddr->sg_list = (struct ibv_sge *) host_to_guest((size_t) vaddr->sg_list); // TODO problem hier for (int i = 0; i < vaddr->num_sge; i++) { host_to_guest_ibv_sge(vaddr->sg_list + i, GUEST); } - // TODO: make this work with an actual list > 1 element. - vaddr->sg_list = host_to_guest_ibv_sge(vaddr->sg_list, HOST); - return vaddr; } @@ -183,7 +124,7 @@ struct ibv_recv_wr * host_to_guest_ibv_recv_wr(struct ibv_recv_wr * wr, addr_typ struct ibv_send_wr * guest_to_host_ibv_send_wr(struct ibv_send_wr * wr) { /* LOG_INFO("Entered guest_to_host_ibv_send_wr()\n"); */ if (wr->next) { - /* LOG_INFO("\twr->next is not NULL\n"); */ + LOG_INFO("\twr->next is not NULL\n"); wr->next = guest_to_host_ibv_send_wr(wr->next); // linked list } @@ -196,12 +137,12 @@ struct ibv_send_wr * guest_to_host_ibv_send_wr(struct ibv_send_wr * wr) { } struct ibv_send_wr * host_to_guest_ibv_send_wr(struct ibv_send_wr * wr, addr_type type) { - /* LOG_INFO("Entered host_to_guest_ibv_send_wr()\n"); */ + LOG_INFO("Entered host_to_guest_ibv_send_wr()\n"); struct ibv_send_wr * vaddr = (type == GUEST) ? wr : (struct ibv_send_wr *) host_to_guest((size_t) wr); if (wr->next) { - /* LOG_INFO("\twr->next is not NULL\n"); */ + LOG_INFO("\twr->next is not NULL\n"); vaddr->next = host_to_guest_ibv_send_wr(vaddr->next, HOST); // linked list } @@ -214,146 +155,208 @@ struct ibv_send_wr * host_to_guest_ibv_send_wr(struct ibv_send_wr * wr, addr_typ } +/* + * struct ibv_device + */ + +/* struct ibv_device * guest_to_host_ibv_device(struct ibv_device * device) { */ + /* // _ops obsolete. */ + /* return (struct ibv_device *) guest_to_host((size_t) device); */ +/* } */ + +/* struct ibv_device * host_to_guest_ibv_device(struct ibv_device * device, addr_type type) { */ + /* struct ibv_device * vaddr = (type == GUEST) ? device */ + /* : (struct ibv_device *) host_to_guest((size_t) device); */ + + /* return vaddr; */ +/* } */ + + +/* + * struct ibv_context + */ + +/* struct ibv_context * guest_to_host_ibv_context(struct ibv_context * context) { */ + /* context->device = guest_to_host_ibv_device(context->device); */ + /* context->abi_compat = guest_to_host_ibv_abi_compat_v2(context->abi_compat); */ + + /* guest_to_host_ibv_context_ops(&context->ops); */ + /* guest_to_host_pthread_mutex_t(&context->mutex); // TODO */ + + /* return (struct ibv_context *) guest_to_host((size_t) context); */ +/* } */ + +/* struct ibv_context * host_to_guest_ibv_context(struct ibv_context * context, addr_type type) { */ + /* struct ibv_context * vaddr = (type == GUEST) ? context */ + /* : (struct ibv_context *) host_to_guest((size_t) context); */ + + /* vaddr->device = host_to_guest_ibv_device(vaddr->device, HOST); */ + /* vaddr->abi_compat = host_to_guest_ibv_abi_compat_v2(vaddr->abi_compat, HOST); */ + + /* host_to_guest_ibv_context_ops(&vaddr->ops, GUEST); */ + /* host_to_guest_pthread_mutex_t(&vaddr->mutex, GUEST); */ + + /* return vaddr; */ +/* } */ + + +/* + * struct ibv_port_attr + */ + +/* struct ibv_port_attr * guest_to_host_ibv_port_attr(struct ibv_port_attr * port_attr) { */ + /* return (struct ibv_port_attr *) guest_to_host((size_t) port_attr); */ +/* } */ + +/* struct ibv_port_attr * host_to_guest_ibv_port_attr(struct ibv_port_attr * port_attr, addr_type type) { */ + /* struct ibv_port_attr * vaddr = (type == GUEST) ? port_attr */ + /* : (struct ibv_port_attr *) host_to_guest((size_t) port_attr); */ + + /* return vaddr; */ +/* } */ + + + /* * struct ibv_comp_channel */ -struct ibv_comp_channel * guest_to_host_ibv_comp_channel(struct ibv_comp_channel * channel) { - channel->context = guest_to_host_ibv_context(channel->context); +/* struct ibv_comp_channel * guest_to_host_ibv_comp_channel(struct ibv_comp_channel * channel) { */ + /* channel->context = guest_to_host_ibv_context(channel->context); */ - return (struct ibv_comp_channel *) guest_to_host((size_t) channel); -} + /* return (struct ibv_comp_channel *) guest_to_host((size_t) channel); */ +/* } */ -struct ibv_comp_channel * host_to_guest_ibv_comp_channel(struct ibv_comp_channel * channel, addr_type type) { - struct ibv_comp_channel * vaddr = (type == GUEST) ? channel - : (struct ibv_comp_channel *) host_to_guest((size_t) channel); +/* struct ibv_comp_channel * host_to_guest_ibv_comp_channel(struct ibv_comp_channel * channel, addr_type type) { */ + /* struct ibv_comp_channel * vaddr = (type == GUEST) ? channel */ + /* : (struct ibv_comp_channel *) host_to_guest((size_t) channel); */ - vaddr->context = host_to_guest_ibv_context(vaddr->context, HOST); + /* vaddr->context = host_to_guest_ibv_context(vaddr->context, HOST); */ - return vaddr; -} + /* return vaddr; */ +/* } */ /* * struct ibv_abi_compat_v2 */ -struct ibv_abi_compat_v2 * guest_to_host_ibv_abi_compat_v2(struct ibv_abi_compat_v2 * abi_compat) { - guest_to_host_ibv_comp_channel(&abi_compat->channel); - guest_to_host_pthread_mutex_t(&abi_compat->in_use); +/* struct ibv_abi_compat_v2 * guest_to_host_ibv_abi_compat_v2(struct ibv_abi_compat_v2 * abi_compat) { */ + /* guest_to_host_ibv_comp_channel(&abi_compat->channel); */ + /* guest_to_host_pthread_mutex_t(&abi_compat->in_use); */ - return (struct ibv_abi_compat_v2 *) guest_to_host((size_t) abi_compat); -} + /* return (struct ibv_abi_compat_v2 *) guest_to_host((size_t) abi_compat); */ +/* } */ -struct ibv_abi_compat_v2 * host_to_guest_ibv_abi_compat_v2(struct ibv_abi_compat_v2 * abi_compat, addr_type type) { - struct ibv_abi_compat_v2 * vaddr = (type == GUEST) ? abi_compat - : (struct ibv_abi_compat_v2 *) host_to_guest((size_t) abi_compat); +/* struct ibv_abi_compat_v2 * host_to_guest_ibv_abi_compat_v2(struct ibv_abi_compat_v2 * abi_compat, addr_type type) { */ + /* struct ibv_abi_compat_v2 * vaddr = (type == GUEST) ? abi_compat */ + /* : (struct ibv_abi_compat_v2 *) host_to_guest((size_t) abi_compat); */ - host_to_guest_ibv_comp_channel(&abi_compat->channel, GUEST); - host_to_guest_pthread_mutex_t(&abi_compat->in_use, GUEST); + /* host_to_guest_ibv_comp_channel(&abi_compat->channel, GUEST); */ + /* host_to_guest_pthread_mutex_t(&abi_compat->in_use, GUEST); */ - return vaddr; -} + /* return vaddr; */ +/* } */ /* * pthread_mutex_t */ -pthread_mutex_t * guest_to_host_pthread_mutex_t(pthread_mutex_t * mutex) { - /* mutex->__m_owner = guest_to_host__pthread_descr(mutex->__m_owner); */ +/* pthread_mutex_t * guest_to_host_pthread_mutex_t(pthread_mutex_t * mutex) { */ + /* [> mutex->__m_owner = guest_to_host__pthread_descr(mutex->__m_owner); <] */ - return (pthread_mutex_t *) guest_to_host((size_t) mutex); -} + /* return (pthread_mutex_t *) guest_to_host((size_t) mutex); */ +/* } */ -pthread_mutex_t * host_to_guest_pthread_mutex_t(pthread_mutex_t * mutex, addr_type type) { - pthread_mutex_t * vaddr = (type == GUEST) ? mutex - : (pthread_mutex_t *) host_to_guest((size_t) mutex); - /* host_to_guest__pthread_descr(mutex->__m_owner); */ +/* pthread_mutex_t * host_to_guest_pthread_mutex_t(pthread_mutex_t * mutex, addr_type type) { */ + /* pthread_mutex_t * vaddr = (type == GUEST) ? mutex */ + /* : (pthread_mutex_t *) host_to_guest((size_t) mutex); */ + /* [> host_to_guest__pthread_descr(mutex->__m_owner); <] */ - return vaddr; -} + /* return vaddr; */ +/* } */ /* * struct ibv_context_ops */ -struct ibv_context_ops * guest_to_host_ibv_context_ops(struct ibv_context_ops * context_ops) { - // TODO: Does this work? - context_ops->query_device = (int (*)(struct ibv_context *, struct ibv_device_attr *)) guest_to_host((size_t) context_ops->query_device); - context_ops->query_port = (int (*)(struct ibv_context *, uint8_t, struct ibv_port_attr *)) guest_to_host((size_t) context_ops->query_port); - context_ops->alloc_pd = (struct ibv_pd * (*)(struct ibv_context *)) guest_to_host((size_t) context_ops->alloc_pd); - context_ops->dealloc_pd = (int (*)(struct ibv_pd *)) guest_to_host((size_t) context_ops->dealloc_pd); - context_ops->reg_mr = (struct ibv_mr * (*)(struct ibv_pd *, void *, size_t, int)) guest_to_host((size_t) context_ops->reg_mr); - context_ops->rereg_mr = (int (*)(struct ibv_mr *, int, struct ibv_pd *, void *, size_t, int)) guest_to_host((size_t) context_ops->rereg_mr); - context_ops->dereg_mr = (int (*)(struct ibv_mr *)) guest_to_host((size_t) context_ops->dereg_mr); - context_ops->alloc_mw = (struct ibv_mw * (*)(struct ibv_pd *, enum ibv_mw_type)) guest_to_host((size_t) context_ops->alloc_mw); - context_ops->bind_mw = (int (*)(struct ibv_qp *, struct ibv_mw *, struct ibv_mw_bind *)) guest_to_host((size_t) context_ops->bind_mw); - context_ops->dealloc_mw = (int (*)(struct ibv_mw *)) guest_to_host((size_t) context_ops->dealloc_mw); - context_ops->create_cq = (struct ibv_cq * (*)(struct ibv_context *, int, struct ibv_comp_channel *, int)) guest_to_host((size_t) context_ops->create_cq); - context_ops->poll_cq = (int (*)(struct ibv_cq *, int, struct ibv_wc *)) guest_to_host((size_t) context_ops->poll_cq); - context_ops->req_notify_cq = (int (*)(struct ibv_cq *, int)) guest_to_host((size_t) context_ops->req_notify_cq); - context_ops->cq_event = (void (*)(struct ibv_cq *)) guest_to_host((size_t) context_ops->cq_event); - context_ops->resize_cq = (int (*)(struct ibv_cq *, int)) guest_to_host((size_t) context_ops->resize_cq); - context_ops->destroy_cq = (int (*)(struct ibv_cq *)) guest_to_host((size_t) context_ops->destroy_cq); - context_ops->create_srq = (struct ibv_srq * (*)(struct ibv_pd *, struct ibv_srq_init_attr *)) guest_to_host((size_t) context_ops->create_srq); - context_ops->modify_srq = (int (*)(struct ibv_srq *, struct ibv_srq_attr *, int)) guest_to_host((size_t) context_ops->modify_srq); - context_ops->query_srq = (int (*)(struct ibv_srq *, struct ibv_srq_attr *)) guest_to_host((size_t) context_ops->query_srq); - context_ops->destroy_srq = (int (*)(struct ibv_srq *)) guest_to_host((size_t) context_ops->destroy_srq); - context_ops->post_srq_recv = (int (*)(struct ibv_srq *, struct ibv_recv_wr *, struct ibv_recv_wr **)) guest_to_host((size_t) context_ops->post_srq_recv); - context_ops->create_qp = (struct ibv_qp * (*)(struct ibv_pd *, struct ibv_qp_init_attr *)) guest_to_host((size_t) context_ops->create_qp); - context_ops->query_qp = (int (*)(struct ibv_qp *, struct ibv_qp_attr *, int, struct ibv_qp_init_attr *)) guest_to_host((size_t) context_ops->query_qp); - context_ops->modify_qp = (int (*)(struct ibv_qp *, struct ibv_qp_attr *, int)) guest_to_host((size_t) context_ops->modify_qp); - context_ops->destroy_qp = (int (*)(struct ibv_qp *)) guest_to_host((size_t) context_ops->destroy_qp); - context_ops->post_send = (int (*)(struct ibv_qp *, struct ibv_send_wr *, struct ibv_send_wr **)) guest_to_host((size_t) context_ops->post_send); - context_ops->post_recv = (int (*)(struct ibv_qp *, struct ibv_recv_wr *, struct ibv_recv_wr **)) guest_to_host((size_t) context_ops->post_recv); - context_ops->create_ah = (struct ibv_ah * (*)(struct ibv_pd *, struct ibv_ah_attr *)) guest_to_host((size_t) context_ops->create_ah); - context_ops->destroy_ah = (int (*)(struct ibv_ah *)) guest_to_host((size_t) context_ops->destroy_ah); - context_ops->attach_mcast = (int (*)(struct ibv_qp *, const union ibv_gid *, uint16_t)) guest_to_host((size_t) context_ops->attach_mcast); - context_ops->detach_mcast = (int (*)(struct ibv_qp *, const union ibv_gid *, uint16_t)) guest_to_host((size_t) context_ops->detach_mcast); - context_ops->async_event = (void (*)(struct ibv_async_event *)) guest_to_host((size_t) context_ops->async_event); +/* struct ibv_context_ops * guest_to_host_ibv_context_ops(struct ibv_context_ops * context_ops) { */ + /* // TODO: Does this work? */ + /* context_ops->query_device = (int (*)(struct ibv_context *, struct ibv_device_attr *)) guest_to_host((size_t) context_ops->query_device); */ + /* context_ops->query_port = (int (*)(struct ibv_context *, uint8_t, struct ibv_port_attr *)) guest_to_host((size_t) context_ops->query_port); */ + /* context_ops->alloc_pd = (struct ibv_pd * (*)(struct ibv_context *)) guest_to_host((size_t) context_ops->alloc_pd); */ + /* context_ops->dealloc_pd = (int (*)(struct ibv_pd *)) guest_to_host((size_t) context_ops->dealloc_pd); */ + /* context_ops->reg_mr = (struct ibv_mr * (*)(struct ibv_pd *, void *, size_t, int)) guest_to_host((size_t) context_ops->reg_mr); */ + /* context_ops->rereg_mr = (int (*)(struct ibv_mr *, int, struct ibv_pd *, void *, size_t, int)) guest_to_host((size_t) context_ops->rereg_mr); */ + /* context_ops->dereg_mr = (int (*)(struct ibv_mr *)) guest_to_host((size_t) context_ops->dereg_mr); */ + /* context_ops->alloc_mw = (struct ibv_mw * (*)(struct ibv_pd *, enum ibv_mw_type)) guest_to_host((size_t) context_ops->alloc_mw); */ + /* context_ops->bind_mw = (int (*)(struct ibv_qp *, struct ibv_mw *, struct ibv_mw_bind *)) guest_to_host((size_t) context_ops->bind_mw); */ + /* context_ops->dealloc_mw = (int (*)(struct ibv_mw *)) guest_to_host((size_t) context_ops->dealloc_mw); */ + /* context_ops->create_cq = (struct ibv_cq * (*)(struct ibv_context *, int, struct ibv_comp_channel *, int)) guest_to_host((size_t) context_ops->create_cq); */ + /* context_ops->poll_cq = (int (*)(struct ibv_cq *, int, struct ibv_wc *)) guest_to_host((size_t) context_ops->poll_cq); */ + /* context_ops->req_notify_cq = (int (*)(struct ibv_cq *, int)) guest_to_host((size_t) context_ops->req_notify_cq); */ + /* context_ops->cq_event = (void (*)(struct ibv_cq *)) guest_to_host((size_t) context_ops->cq_event); */ + /* context_ops->resize_cq = (int (*)(struct ibv_cq *, int)) guest_to_host((size_t) context_ops->resize_cq); */ + /* context_ops->destroy_cq = (int (*)(struct ibv_cq *)) guest_to_host((size_t) context_ops->destroy_cq); */ + /* context_ops->create_srq = (struct ibv_srq * (*)(struct ibv_pd *, struct ibv_srq_init_attr *)) guest_to_host((size_t) context_ops->create_srq); */ + /* context_ops->modify_srq = (int (*)(struct ibv_srq *, struct ibv_srq_attr *, int)) guest_to_host((size_t) context_ops->modify_srq); */ + /* context_ops->query_srq = (int (*)(struct ibv_srq *, struct ibv_srq_attr *)) guest_to_host((size_t) context_ops->query_srq); */ + /* context_ops->destroy_srq = (int (*)(struct ibv_srq *)) guest_to_host((size_t) context_ops->destroy_srq); */ + /* context_ops->post_srq_recv = (int (*)(struct ibv_srq *, struct ibv_recv_wr *, struct ibv_recv_wr **)) guest_to_host((size_t) context_ops->post_srq_recv); */ + /* context_ops->create_qp = (struct ibv_qp * (*)(struct ibv_pd *, struct ibv_qp_init_attr *)) guest_to_host((size_t) context_ops->create_qp); */ + /* context_ops->query_qp = (int (*)(struct ibv_qp *, struct ibv_qp_attr *, int, struct ibv_qp_init_attr *)) guest_to_host((size_t) context_ops->query_qp); */ + /* context_ops->modify_qp = (int (*)(struct ibv_qp *, struct ibv_qp_attr *, int)) guest_to_host((size_t) context_ops->modify_qp); */ + /* context_ops->destroy_qp = (int (*)(struct ibv_qp *)) guest_to_host((size_t) context_ops->destroy_qp); */ + /* context_ops->post_send = (int (*)(struct ibv_qp *, struct ibv_send_wr *, struct ibv_send_wr **)) guest_to_host((size_t) context_ops->post_send); */ + /* context_ops->post_recv = (int (*)(struct ibv_qp *, struct ibv_recv_wr *, struct ibv_recv_wr **)) guest_to_host((size_t) context_ops->post_recv); */ + /* context_ops->create_ah = (struct ibv_ah * (*)(struct ibv_pd *, struct ibv_ah_attr *)) guest_to_host((size_t) context_ops->create_ah); */ + /* context_ops->destroy_ah = (int (*)(struct ibv_ah *)) guest_to_host((size_t) context_ops->destroy_ah); */ + /* context_ops->attach_mcast = (int (*)(struct ibv_qp *, const union ibv_gid *, uint16_t)) guest_to_host((size_t) context_ops->attach_mcast); */ + /* context_ops->detach_mcast = (int (*)(struct ibv_qp *, const union ibv_gid *, uint16_t)) guest_to_host((size_t) context_ops->detach_mcast); */ + /* context_ops->async_event = (void (*)(struct ibv_async_event *)) guest_to_host((size_t) context_ops->async_event); */ - return (struct ibv_context_ops *) guest_to_host((size_t) context_ops); -} + /* return (struct ibv_context_ops *) guest_to_host((size_t) context_ops); */ +/* } */ -struct ibv_context_ops * host_to_guest_ibv_context_ops( - struct ibv_context_ops * context_ops, addr_type type) { - struct ibv_context_ops * vaddr = (type == GUEST) ? context_ops - : (struct ibv_context_ops *) host_to_guest((size_t) context_ops); +/* struct ibv_context_ops * host_to_guest_ibv_context_ops( */ + /* struct ibv_context_ops * context_ops, addr_type type) { */ + /* struct ibv_context_ops * vaddr = (type == GUEST) ? context_ops */ + /* : (struct ibv_context_ops *) host_to_guest((size_t) context_ops); */ - vaddr->query_device = (int (*)(struct ibv_context *, struct ibv_device_attr *)) host_to_guest((size_t) vaddr->query_device); - vaddr->query_port = (int (*)(struct ibv_context *, uint8_t, struct ibv_port_attr *)) host_to_guest((size_t) vaddr->query_port); - vaddr->alloc_pd = (struct ibv_pd * (*)(struct ibv_context *)) host_to_guest((size_t) vaddr->alloc_pd); - vaddr->dealloc_pd = (int (*)(struct ibv_pd *)) host_to_guest((size_t) vaddr->dealloc_pd); - vaddr->reg_mr = (struct ibv_mr * (*)(struct ibv_pd *, void *, size_t, int)) host_to_guest((size_t) vaddr->reg_mr); - vaddr->rereg_mr = (int (*)(struct ibv_mr *, int, struct ibv_pd *, void *, size_t, int)) host_to_guest((size_t) vaddr->rereg_mr); - vaddr->dereg_mr = (int (*)(struct ibv_mr *)) host_to_guest((size_t) vaddr->dereg_mr); - vaddr->alloc_mw = (struct ibv_mw * (*)(struct ibv_pd *, enum ibv_mw_type)) host_to_guest((size_t) vaddr->alloc_mw); - vaddr->bind_mw = (int (*)(struct ibv_qp *, struct ibv_mw *, struct ibv_mw_bind *)) host_to_guest((size_t) vaddr->bind_mw); - vaddr->dealloc_mw = (int (*)(struct ibv_mw *)) host_to_guest((size_t) vaddr->dealloc_mw); - vaddr->create_cq = (struct ibv_cq * (*)(struct ibv_context *, int, struct ibv_comp_channel *, int)) host_to_guest((size_t) vaddr->create_cq); - vaddr->poll_cq = (int (*)(struct ibv_cq *, int, struct ibv_wc *)) host_to_guest((size_t) vaddr->poll_cq); - vaddr->req_notify_cq = (int (*)(struct ibv_cq *, int)) host_to_guest((size_t) vaddr->req_notify_cq); - vaddr->cq_event = (void (*)(struct ibv_cq *)) host_to_guest((size_t) vaddr->cq_event); - vaddr->resize_cq = (int (*)(struct ibv_cq *, int)) host_to_guest((size_t) vaddr->resize_cq); - vaddr->destroy_cq = (int (*)(struct ibv_cq *)) host_to_guest((size_t) vaddr->destroy_cq); - vaddr->create_srq = (struct ibv_srq * (*)(struct ibv_pd *, struct ibv_srq_init_attr *)) host_to_guest((size_t) vaddr->create_srq); - vaddr->modify_srq = (int (*)(struct ibv_srq *, struct ibv_srq_attr *, int)) host_to_guest((size_t) vaddr->modify_srq); - vaddr->query_srq = (int (*)(struct ibv_srq *, struct ibv_srq_attr *)) host_to_guest((size_t) vaddr->query_srq); - vaddr->destroy_srq = (int (*)(struct ibv_srq *)) host_to_guest((size_t) vaddr->destroy_srq); - vaddr->post_srq_recv = (int (*)(struct ibv_srq *, struct ibv_recv_wr *, struct ibv_recv_wr **)) host_to_guest((size_t) vaddr->post_srq_recv); - vaddr->create_qp = (struct ibv_qp * (*)(struct ibv_pd *, struct ibv_qp_init_attr *)) host_to_guest((size_t) vaddr->create_qp); - vaddr->query_qp = (int (*)(struct ibv_qp *, struct ibv_qp_attr *, int, struct ibv_qp_init_attr *)) host_to_guest((size_t) vaddr->query_qp); - vaddr->modify_qp = (int (*)(struct ibv_qp *, struct ibv_qp_attr *, int)) host_to_guest((size_t) vaddr->modify_qp); - vaddr->destroy_qp = (int (*)(struct ibv_qp *)) host_to_guest((size_t) vaddr->destroy_qp); - vaddr->post_send = (int (*)(struct ibv_qp *, struct ibv_send_wr *, struct ibv_send_wr **)) host_to_guest((size_t) vaddr->post_send); - vaddr->post_recv = (int (*)(struct ibv_qp *, struct ibv_recv_wr *, struct ibv_recv_wr **)) host_to_guest((size_t) vaddr->post_recv); - vaddr->create_ah = (struct ibv_ah * (*)(struct ibv_pd *, struct ibv_ah_attr *)) host_to_guest((size_t) vaddr->create_ah); - vaddr->destroy_ah = (int (*)(struct ibv_ah *)) host_to_guest((size_t) vaddr->destroy_ah); - vaddr->attach_mcast = (int (*)(struct ibv_qp *, const union ibv_gid *, uint16_t)) host_to_guest((size_t) vaddr->attach_mcast); - vaddr->detach_mcast = (int (*)(struct ibv_qp *, const union ibv_gid *, uint16_t)) host_to_guest((size_t) vaddr->detach_mcast); - vaddr->async_event = (void (*)(struct ibv_async_event *)) host_to_guest((size_t) vaddr->async_event); + /* vaddr->query_device = (int (*)(struct ibv_context *, struct ibv_device_attr *)) host_to_guest((size_t) vaddr->query_device); */ + /* vaddr->query_port = (int (*)(struct ibv_context *, uint8_t, struct ibv_port_attr *)) host_to_guest((size_t) vaddr->query_port); */ + /* vaddr->alloc_pd = (struct ibv_pd * (*)(struct ibv_context *)) host_to_guest((size_t) vaddr->alloc_pd); */ + /* vaddr->dealloc_pd = (int (*)(struct ibv_pd *)) host_to_guest((size_t) vaddr->dealloc_pd); */ + /* vaddr->reg_mr = (struct ibv_mr * (*)(struct ibv_pd *, void *, size_t, int)) host_to_guest((size_t) vaddr->reg_mr); */ + /* vaddr->rereg_mr = (int (*)(struct ibv_mr *, int, struct ibv_pd *, void *, size_t, int)) host_to_guest((size_t) vaddr->rereg_mr); */ + /* vaddr->dereg_mr = (int (*)(struct ibv_mr *)) host_to_guest((size_t) vaddr->dereg_mr); */ + /* vaddr->alloc_mw = (struct ibv_mw * (*)(struct ibv_pd *, enum ibv_mw_type)) host_to_guest((size_t) vaddr->alloc_mw); */ + /* vaddr->bind_mw = (int (*)(struct ibv_qp *, struct ibv_mw *, struct ibv_mw_bind *)) host_to_guest((size_t) vaddr->bind_mw); */ + /* vaddr->dealloc_mw = (int (*)(struct ibv_mw *)) host_to_guest((size_t) vaddr->dealloc_mw); */ + /* vaddr->create_cq = (struct ibv_cq * (*)(struct ibv_context *, int, struct ibv_comp_channel *, int)) host_to_guest((size_t) vaddr->create_cq); */ + /* vaddr->poll_cq = (int (*)(struct ibv_cq *, int, struct ibv_wc *)) host_to_guest((size_t) vaddr->poll_cq); */ + /* vaddr->req_notify_cq = (int (*)(struct ibv_cq *, int)) host_to_guest((size_t) vaddr->req_notify_cq); */ + /* vaddr->cq_event = (void (*)(struct ibv_cq *)) host_to_guest((size_t) vaddr->cq_event); */ + /* vaddr->resize_cq = (int (*)(struct ibv_cq *, int)) host_to_guest((size_t) vaddr->resize_cq); */ + /* vaddr->destroy_cq = (int (*)(struct ibv_cq *)) host_to_guest((size_t) vaddr->destroy_cq); */ + /* vaddr->create_srq = (struct ibv_srq * (*)(struct ibv_pd *, struct ibv_srq_init_attr *)) host_to_guest((size_t) vaddr->create_srq); */ + /* vaddr->modify_srq = (int (*)(struct ibv_srq *, struct ibv_srq_attr *, int)) host_to_guest((size_t) vaddr->modify_srq); */ + /* vaddr->query_srq = (int (*)(struct ibv_srq *, struct ibv_srq_attr *)) host_to_guest((size_t) vaddr->query_srq); */ + /* vaddr->destroy_srq = (int (*)(struct ibv_srq *)) host_to_guest((size_t) vaddr->destroy_srq); */ + /* vaddr->post_srq_recv = (int (*)(struct ibv_srq *, struct ibv_recv_wr *, struct ibv_recv_wr **)) host_to_guest((size_t) vaddr->post_srq_recv); */ + /* vaddr->create_qp = (struct ibv_qp * (*)(struct ibv_pd *, struct ibv_qp_init_attr *)) host_to_guest((size_t) vaddr->create_qp); */ + /* vaddr->query_qp = (int (*)(struct ibv_qp *, struct ibv_qp_attr *, int, struct ibv_qp_init_attr *)) host_to_guest((size_t) vaddr->query_qp); */ + /* vaddr->modify_qp = (int (*)(struct ibv_qp *, struct ibv_qp_attr *, int)) host_to_guest((size_t) vaddr->modify_qp); */ + /* vaddr->destroy_qp = (int (*)(struct ibv_qp *)) host_to_guest((size_t) vaddr->destroy_qp); */ + /* vaddr->post_send = (int (*)(struct ibv_qp *, struct ibv_send_wr *, struct ibv_send_wr **)) host_to_guest((size_t) vaddr->post_send); */ + /* vaddr->post_recv = (int (*)(struct ibv_qp *, struct ibv_recv_wr *, struct ibv_recv_wr **)) host_to_guest((size_t) vaddr->post_recv); */ + /* vaddr->create_ah = (struct ibv_ah * (*)(struct ibv_pd *, struct ibv_ah_attr *)) host_to_guest((size_t) vaddr->create_ah); */ + /* vaddr->destroy_ah = (int (*)(struct ibv_ah *)) host_to_guest((size_t) vaddr->destroy_ah); */ + /* vaddr->attach_mcast = (int (*)(struct ibv_qp *, const union ibv_gid *, uint16_t)) host_to_guest((size_t) vaddr->attach_mcast); */ + /* vaddr->detach_mcast = (int (*)(struct ibv_qp *, const union ibv_gid *, uint16_t)) host_to_guest((size_t) vaddr->detach_mcast); */ + /* vaddr->async_event = (void (*)(struct ibv_async_event *)) host_to_guest((size_t) vaddr->async_event); */ - return vaddr; -} + /* return vaddr; */ +/* } */ diff --git a/tools/ibv_code_generator/function-prototypes.txt b/tools/ibv_code_generator/function-prototypes.txt index 6f9e761fc..2824ca465 100644 --- a/tools/ibv_code_generator/function-prototypes.txt +++ b/tools/ibv_code_generator/function-prototypes.txt @@ -1,70 +1,70 @@ -const char * ibv_wc_status_str(enum ibv_wc_status status) -int ibv_rate_to_mult(enum ibv_rate rate) -enum ibv_rate mult_to_ibv_rate(int mult) -int ibv_rate_to_mbps(enum ibv_rate rate) -enum ibv_rate mbps_to_ibv_rate(int mbps) -struct verbs_context * verbs_get_ctx(struct ibv_context * ctx) -struct ibv_device ** ibv_get_device_list(int * num_devices) -void ibv_free_device_list(struct ibv_device ** list) -const char * ibv_get_device_name(struct ibv_device * device) -__be64 ibv_get_device_guid(struct ibv_device * device) -struct ibv_context * ibv_open_device(struct ibv_device * device) -int ibv_close_device(struct ibv_context * context) -int ibv_get_async_event(struct ibv_context * context,struct ibv_async_event * event) -void ibv_ack_async_event(struct ibv_async_event * event) -int ibv_query_device(struct ibv_context * context,struct ibv_device_attr * device_attr) -int ibv_query_port(struct ibv_context * context,uint8_t port_num,struct ibv_port_attr * port_attr) -int ___ibv_query_port(struct ibv_context * context,uint8_t port_num,struct ibv_port_attr * port_attr) -int ibv_query_gid(struct ibv_context * context,uint8_t port_num,int index,union ibv_gid * gid) -int ibv_query_pkey(struct ibv_context * context,uint8_t port_num,int index,__be16 * pkey) -struct ibv_pd * ibv_alloc_pd(struct ibv_context * context) -int ibv_dealloc_pd(struct ibv_pd * pd) -struct ibv_flow * ibv_create_flow(struct ibv_qp * qp,struct ibv_flow_attr * flow) -int ibv_destroy_flow(struct ibv_flow * flow_id) -struct ibv_xrcd * ibv_open_xrcd(struct ibv_context * context,struct ibv_xrcd_init_attr * xrcd_init_attr) -int ibv_close_xrcd(struct ibv_xrcd * xrcd) -struct ibv_mr * ibv_reg_mr(struct ibv_pd * pd,void * addr,int length,int access) -int ibv_rereg_mr(struct ibv_mr * mr,int flags,struct ibv_pd * pd,void * addr,int length,int access) -int ibv_dereg_mr(struct ibv_mr * mr) -struct ibv_mw * ibv_alloc_mw(struct ibv_pd * pd,enum ibv_mw_type type) -int ibv_dealloc_mw(struct ibv_mw * mw) -uint32_t ibv_inc_rkey(uint32_t rkey) -int ibv_bind_mw(struct ibv_qp * qp,struct ibv_mw * mw,struct ibv_mw_bind * mw_bind) -struct ibv_comp_channel * ibv_create_comp_channel(struct ibv_context * context) -int ibv_destroy_comp_channel(struct ibv_comp_channel * channel) -struct ibv_cq * ibv_create_cq(struct ibv_context * context,int cqe,void * cq_context,struct ibv_comp_channel * channel,int comp_vector) -int ibv_resize_cq(struct ibv_cq * cq,int cqe) -int ibv_destroy_cq(struct ibv_cq * cq) -int ibv_get_cq_event(struct ibv_comp_channel * channel,struct ibv_cq ** cq,void ** cq_context) -void ibv_ack_cq_events(struct ibv_cq * cq,unsigned int nevents) -int ibv_poll_cq(struct ibv_cq * cq,int num_entries,struct ibv_wc * wc) -int ibv_req_notify_cq(struct ibv_cq * cq,int solicited_only) -struct ibv_srq * ibv_create_srq(struct ibv_pd * pd,struct ibv_srq_init_attr * srq_init_attr) -struct ibv_srq * ibv_create_srq_ex(struct ibv_context * context,struct ibv_srq_init_attr_ex * srq_init_attr_ex) -int ibv_modify_srq(struct ibv_srq * srq,struct ibv_srq_attr * srq_attr,int srq_attr_mask) -int ibv_query_srq(struct ibv_srq * srq,struct ibv_srq_attr * srq_attr) -int ibv_get_srq_num(struct ibv_srq * srq,uint32_t * srq_num) -int ibv_destroy_srq(struct ibv_srq * srq) -int ibv_post_srq_recv(struct ibv_srq * srq,struct ibv_recv_wr * recv_wr,struct ibv_recv_wr ** bad_recv_wr) -struct ibv_qp * ibv_create_qp(struct ibv_pd * pd,struct ibv_qp_init_attr * qp_init_attr) -struct ibv_qp * ibv_create_qp_ex(struct ibv_context * context,struct ibv_qp_init_attr_ex * qp_init_attr_ex) -int ibv_query_device_ex(struct ibv_context * context,const struct ibv_query_device_ex_input * input,struct ibv_device_attr_ex * attr) -struct ibv_qp * ibv_open_qp(struct ibv_context * context,struct ibv_qp_open_attr * qp_open_attr) -int ibv_modify_qp(struct ibv_qp * qp,struct ibv_qp_attr * attr,int attr_mask) -int ibv_query_qp(struct ibv_qp * qp,struct ibv_qp_attr * attr,int attr_mask,struct ibv_qp_init_attr * init_attr) -int ibv_destroy_qp(struct ibv_qp * qp) -int ibv_post_send(struct ibv_qp * qp,struct ibv_send_wr * wr,struct ibv_send_wr ** bad_wr) -int ibv_post_recv(struct ibv_qp * qp,struct ibv_recv_wr * wr,struct ibv_recv_wr ** bad_wr) -struct ibv_ah * ibv_create_ah(struct ibv_pd * pd,struct ibv_ah_attr * attr) -int ibv_init_ah_from_wc(struct ibv_context * context,uint8_t port_num,struct ibv_wc * wc,struct ibv_grh * grh,struct ibv_ah_attr * ah_attr) -struct ibv_ah * ibv_create_ah_from_wc(struct ibv_pd * pd,struct ibv_wc * wc,struct ibv_grh * grh,uint8_t port_num) -int ibv_destroy_ah(struct ibv_ah * ah) -int ibv_attach_mcast(struct ibv_qp * qp,const union ibv_gid * gid,uint16_t lid) -int ibv_detach_mcast(struct ibv_qp * qp,const union ibv_gid * gid,uint16_t lid) -int ibv_fork_init() -const char * ibv_node_type_str(enum ibv_node_type node_type) -const char * ibv_port_state_str(enum ibv_port_state port_state) -const char * ibv_event_type_str(enum ibv_event_type event) -int ibv_is_qpt_supported(uint32_t caps,enum ibv_qp_type qpt) -uint32_t ibv_get_mr_lkey(struct ibv_mr * mr) -uint32_t ibv_get_qp_num(struct ibv_qp * qp) +const char * ibv_wc_status_str(enum ibv_wc_status status) +int ibv_rate_to_mult(enum ibv_rate rate) +enum ibv_rate mult_to_ibv_rate(int mult) +int ibv_rate_to_mbps(enum ibv_rate rate) +enum ibv_rate mbps_to_ibv_rate(int mbps) +struct verbs_context * verbs_get_ctx(struct ibv_context * ctx) +struct ibv_device ** ibv_get_device_list(int * num_devices) +void ibv_free_device_list(struct ibv_device ** list) +const char * ibv_get_device_name(struct ibv_device * device) +__be64 ibv_get_device_guid(struct ibv_device * device) +struct ibv_context * ibv_open_device(struct ibv_device * device) +int ibv_close_device(struct ibv_context * context) +int ibv_get_async_event(struct ibv_context * context,struct ibv_async_event * event) +void ibv_ack_async_event(struct ibv_async_event * event) +int ibv_query_device(struct ibv_context * context,struct ibv_device_attr * device_attr) +int ibv_query_port(struct ibv_context * context,uint8_t port_num,struct ibv_port_attr * port_attr) +int ___ibv_query_port(struct ibv_context * context,uint8_t port_num,struct ibv_port_attr * port_attr) +int ibv_query_gid(struct ibv_context * context,uint8_t port_num,int index,union ibv_gid * gid) +int ibv_query_pkey(struct ibv_context * context,uint8_t port_num,int index,__be16 * pkey) +struct ibv_pd * ibv_alloc_pd(struct ibv_context * context) +int ibv_dealloc_pd(struct ibv_pd * pd) +struct ibv_flow * ibv_create_flow(struct ibv_qp * qp,struct ibv_flow_attr * flow) +int ibv_destroy_flow(struct ibv_flow * flow_id) +struct ibv_xrcd * ibv_open_xrcd(struct ibv_context * context,struct ibv_xrcd_init_attr * xrcd_init_attr) +int ibv_close_xrcd(struct ibv_xrcd * xrcd) +struct ibv_mr * ibv_reg_mr(struct ibv_pd * pd,void * addr,int length,int access) +int ibv_rereg_mr(struct ibv_mr * mr,int flags,struct ibv_pd * pd,void * addr,int length,int access) +int ibv_dereg_mr(struct ibv_mr * mr) +struct ibv_mw * ibv_alloc_mw(struct ibv_pd * pd,enum ibv_mw_type type) +int ibv_dealloc_mw(struct ibv_mw * mw) +uint32_t ibv_inc_rkey(uint32_t rkey) +int ibv_bind_mw(struct ibv_qp * qp,struct ibv_mw * mw,struct ibv_mw_bind * mw_bind) +struct ibv_comp_channel * ibv_create_comp_channel(struct ibv_context * context) +int ibv_destroy_comp_channel(struct ibv_comp_channel * channel) +struct ibv_cq * ibv_create_cq(struct ibv_context * context,int cqe,void * cq_context,struct ibv_comp_channel * channel,int comp_vector) +int ibv_resize_cq(struct ibv_cq * cq,int cqe) +int ibv_destroy_cq(struct ibv_cq * cq) +int ibv_get_cq_event(struct ibv_comp_channel * channel,struct ibv_cq ** cq,void ** cq_context) +void ibv_ack_cq_events(struct ibv_cq * cq,unsigned int nevents) +int ibv_poll_cq(struct ibv_cq * cq,int num_entries,struct ibv_wc * wc) +int ibv_req_notify_cq(struct ibv_cq * cq,int solicited_only) +struct ibv_srq * ibv_create_srq(struct ibv_pd * pd,struct ibv_srq_init_attr * srq_init_attr) +struct ibv_srq * ibv_create_srq_ex(struct ibv_context * context,struct ibv_srq_init_attr_ex * srq_init_attr_ex) +int ibv_modify_srq(struct ibv_srq * srq,struct ibv_srq_attr * srq_attr,int srq_attr_mask) +int ibv_query_srq(struct ibv_srq * srq,struct ibv_srq_attr * srq_attr) +int ibv_get_srq_num(struct ibv_srq * srq,uint32_t * srq_num) +int ibv_destroy_srq(struct ibv_srq * srq) +int ibv_post_srq_recv(struct ibv_srq * srq,struct ibv_recv_wr * recv_wr,struct ibv_recv_wr ** bad_recv_wr) +struct ibv_qp * ibv_create_qp(struct ibv_pd * pd,struct ibv_qp_init_attr * qp_init_attr) +struct ibv_qp * ibv_create_qp_ex(struct ibv_context * context,struct ibv_qp_init_attr_ex * qp_init_attr_ex) +int ibv_query_device_ex(struct ibv_context * context,const struct ibv_query_device_ex_input * input,struct ibv_device_attr_ex * attr) +struct ibv_qp * ibv_open_qp(struct ibv_context * context,struct ibv_qp_open_attr * qp_open_attr) +int ibv_modify_qp(struct ibv_qp * qp,struct ibv_qp_attr * attr,int attr_mask) +int ibv_query_qp(struct ibv_qp * qp,struct ibv_qp_attr * attr,int attr_mask,struct ibv_qp_init_attr * init_attr) +int ibv_destroy_qp(struct ibv_qp * qp) +int ibv_post_send(struct ibv_qp * qp,struct ibv_send_wr * wr,struct ibv_send_wr ** bad_wr) +int ibv_post_recv(struct ibv_qp * qp,struct ibv_recv_wr * wr,struct ibv_recv_wr ** bad_wr) +struct ibv_ah * ibv_create_ah(struct ibv_pd * pd,struct ibv_ah_attr * attr) +int ibv_init_ah_from_wc(struct ibv_context * context,uint8_t port_num,struct ibv_wc * wc,struct ibv_grh * grh,struct ibv_ah_attr * ah_attr) +struct ibv_ah * ibv_create_ah_from_wc(struct ibv_pd * pd,struct ibv_wc * wc,struct ibv_grh * grh,uint8_t port_num) +int ibv_destroy_ah(struct ibv_ah * ah) +int ibv_attach_mcast(struct ibv_qp * qp,const union ibv_gid * gid,uint16_t lid) +int ibv_detach_mcast(struct ibv_qp * qp,const union ibv_gid * gid,uint16_t lid) +int ibv_fork_init() +const char * ibv_node_type_str(enum ibv_node_type node_type) +const char * ibv_port_state_str(enum ibv_port_state port_state) +const char * ibv_event_type_str(enum ibv_event_type event) +int ibv_is_qpt_supported(uint32_t caps,enum ibv_qp_type qpt) +uint32_t ibv_get_mr_lkey(struct ibv_mr * mr) +uint32_t ibv_get_qp_num(struct ibv_qp * qp) diff --git a/usr/tests/CMakeLists.txt b/usr/tests/CMakeLists.txt index 4d20651a3..aa181d30d 100644 --- a/usr/tests/CMakeLists.txt +++ b/usr/tests/CMakeLists.txt @@ -11,7 +11,8 @@ add_executable(pi pi.go) add_executable(ib-test ib-test.c) #add_executable(ib-pingpong ib/pingpong.c ib/pingpong.h ib/pingpong-ud.c) -add_executable(ib-pingpong ib/pingpong.c ib/pingpong-ud.c) +add_executable(ib-pingpong-ud ib/pingpong.c ib/pingpong-ud.c) +add_executable(ib-pingpong-rc ib/pingpong.c ib/pingpong-rc.c) #target_link_libraries(ib-test ibverbs) add_executable(test-malloc test-malloc.c) diff --git a/usr/tests/ib/pingpong-rc.c b/usr/tests/ib/pingpong-rc.c new file mode 100644 index 000000000..fe445089b --- /dev/null +++ b/usr/tests/ib/pingpong-rc.c @@ -0,0 +1,1057 @@ +/* + * Copyright (c) 2005 Topspin Communications. 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. + */ +#define _GNU_SOURCE +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pingpong.h" + +#include + +enum { + PINGPONG_RECV_WRID = 1, + PINGPONG_SEND_WRID = 2, +}; + +static int page_size; +static int use_odp; +static int use_ts; +static int validate_buf; + +struct pingpong_context { + struct ibv_context *context; + struct ibv_comp_channel *channel; + struct ibv_pd *pd; + struct ibv_mr *mr; + union { + struct ibv_cq *cq; + struct ibv_cq_ex *cq_ex; + } cq_s; + struct ibv_qp *qp; + char *buf; + int size; + int send_flags; + int rx_depth; + int pending; + struct ibv_port_attr portinfo; + uint64_t completion_timestamp_mask; +}; + +static struct ibv_cq *pp_cq(struct pingpong_context *ctx) +{ + return use_ts ? ibv_cq_ex_to_cq(ctx->cq_s.cq_ex) : + ctx->cq_s.cq; +} + +struct pingpong_dest { + int lid; + int qpn; + int psn; + union ibv_gid gid; +}; + +static int pp_connect_ctx(struct pingpong_context *ctx, int port, int my_psn, + enum ibv_mtu mtu, int sl, + struct pingpong_dest *dest, int sgid_idx) +{ + struct ibv_qp_attr attr = { + .qp_state = IBV_QPS_RTR, + .path_mtu = mtu, + .dest_qp_num = dest->qpn, + .rq_psn = dest->psn, + .max_dest_rd_atomic = 1, + .min_rnr_timer = 12, + .ah_attr = { + .is_global = 0, + .dlid = dest->lid, + .sl = sl, + .src_path_bits = 0, + .port_num = port + } + }; + + if (dest->gid.global.interface_id) { + attr.ah_attr.is_global = 1; + attr.ah_attr.grh.hop_limit = 1; + attr.ah_attr.grh.dgid = dest->gid; + attr.ah_attr.grh.sgid_index = sgid_idx; + } + if (ibv_modify_qp(ctx->qp, &attr, + IBV_QP_STATE | + IBV_QP_AV | + IBV_QP_PATH_MTU | + IBV_QP_DEST_QPN | + IBV_QP_RQ_PSN | + IBV_QP_MAX_DEST_RD_ATOMIC | + IBV_QP_MIN_RNR_TIMER)) { + fprintf(stderr, "Failed to modify QP to RTR\n"); + return 1; + } + + attr.qp_state = IBV_QPS_RTS; + attr.timeout = 14; + attr.retry_cnt = 7; + attr.rnr_retry = 7; + attr.sq_psn = my_psn; + attr.max_rd_atomic = 1; + if (ibv_modify_qp(ctx->qp, &attr, + IBV_QP_STATE | + IBV_QP_TIMEOUT | + IBV_QP_RETRY_CNT | + IBV_QP_RNR_RETRY | + IBV_QP_SQ_PSN | + IBV_QP_MAX_QP_RD_ATOMIC)) { + fprintf(stderr, "Failed to modify QP to RTS\n"); + return 1; + } + + return 0; +} + +static struct pingpong_dest *pp_client_exch_dest(const char *servername, int port, + const struct pingpong_dest *my_dest) +{ + struct addrinfo *res, *t; + struct addrinfo hints = { + .ai_family = AF_UNSPEC, + .ai_socktype = SOCK_STREAM + }; + char *service; + char msg[sizeof "0000:000000:000000:00000000000000000000000000000000"]; + int n; + int sockfd = -1; + struct pingpong_dest *rem_dest = NULL; + char gid[33]; + + if (asprintf(&service, "%d", port) < 0) + return NULL; + + n = getaddrinfo(servername, service, &hints, &res); + + if (n < 0) { + fprintf(stderr, "%s for %s:%d\n", gai_strerror(n), servername, port); + free(service); + return NULL; + } + + for (t = res; t; t = t->ai_next) { + sockfd = socket(t->ai_family, t->ai_socktype, t->ai_protocol); + if (sockfd >= 0) { + if (!connect(sockfd, t->ai_addr, t->ai_addrlen)) + break; + close(sockfd); + sockfd = -1; + } + } + + freeaddrinfo(res); + free(service); + + if (sockfd < 0) { + fprintf(stderr, "Couldn't connect to %s:%d\n", servername, port); + return NULL; + } + + gid_to_wire_gid(&my_dest->gid, gid); + sprintf(msg, "%04x:%06x:%06x:%s", my_dest->lid, my_dest->qpn, + my_dest->psn, gid); + if (write(sockfd, msg, sizeof msg) != sizeof msg) { + fprintf(stderr, "Couldn't send local address\n"); + goto out; + } + + if (read(sockfd, msg, sizeof msg) != sizeof msg || + write(sockfd, "done", sizeof "done") != sizeof "done") { + perror("client read/write"); + fprintf(stderr, "Couldn't read/write remote address\n"); + goto out; + } + + rem_dest = malloc(sizeof *rem_dest); + if (!rem_dest) + goto out; + + sscanf(msg, "%x:%x:%x:%s", &rem_dest->lid, &rem_dest->qpn, + &rem_dest->psn, gid); + wire_gid_to_gid(gid, &rem_dest->gid); + +out: + close(sockfd); + return rem_dest; +} + +static struct pingpong_dest *pp_server_exch_dest(struct pingpong_context *ctx, + int ib_port, enum ibv_mtu mtu, + int port, int sl, + const struct pingpong_dest *my_dest, + int sgid_idx) +{ + struct addrinfo *res, *t; + struct addrinfo hints = { + .ai_flags = AI_PASSIVE, + .ai_family = AF_UNSPEC, + .ai_socktype = SOCK_STREAM + }; + char *service; + char msg[sizeof "0000:000000:000000:00000000000000000000000000000000"]; + int n; + int sockfd = -1, connfd; + struct pingpong_dest *rem_dest = NULL; + char gid[33]; + + if (asprintf(&service, "%d", port) < 0) + return NULL; + + n = getaddrinfo(NULL, service, &hints, &res); + + if (n < 0) { + fprintf(stderr, "%s for port %d\n", gai_strerror(n), port); + free(service); + return NULL; + } + + for (t = res; t; t = t->ai_next) { + sockfd = socket(t->ai_family, t->ai_socktype, t->ai_protocol); + if (sockfd >= 0) { + n = 1; + + setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &n, sizeof n); + + if (!bind(sockfd, t->ai_addr, t->ai_addrlen)) + break; + close(sockfd); + sockfd = -1; + } + } + + freeaddrinfo(res); + free(service); + + if (sockfd < 0) { + fprintf(stderr, "Couldn't listen to port %d\n", port); + return NULL; + } + + listen(sockfd, 1); + connfd = accept(sockfd, NULL, NULL); + close(sockfd); + if (connfd < 0) { + fprintf(stderr, "accept() failed\n"); + return NULL; + } + + n = read(connfd, msg, sizeof msg); + if (n != sizeof msg) { + perror("server read"); + fprintf(stderr, "%d/%d: Couldn't read remote address\n", n, (int) sizeof msg); + goto out; + } + + rem_dest = malloc(sizeof *rem_dest); + if (!rem_dest) + goto out; + + sscanf(msg, "%x:%x:%x:%s", &rem_dest->lid, &rem_dest->qpn, + &rem_dest->psn, gid); + wire_gid_to_gid(gid, &rem_dest->gid); + + if (pp_connect_ctx(ctx, ib_port, my_dest->psn, mtu, sl, rem_dest, + sgid_idx)) { + fprintf(stderr, "Couldn't connect to remote QP\n"); + free(rem_dest); + rem_dest = NULL; + goto out; + } + + + gid_to_wire_gid(&my_dest->gid, gid); + sprintf(msg, "%04x:%06x:%06x:%s", my_dest->lid, my_dest->qpn, + my_dest->psn, gid); + if (write(connfd, msg, sizeof msg) != sizeof msg || + read(connfd, msg, sizeof msg) != sizeof "done") { + fprintf(stderr, "Couldn't send/recv local address\n"); + free(rem_dest); + rem_dest = NULL; + goto out; + } + + +out: + close(connfd); + return rem_dest; +} + +static struct pingpong_context *pp_init_ctx(struct ibv_device *ib_dev, int size, + int rx_depth, int port, + int use_event) +{ + struct pingpong_context *ctx; + int access_flags = IBV_ACCESS_LOCAL_WRITE; + + ctx = calloc(1, sizeof *ctx); + if (!ctx) + return NULL; + + ctx->size = size; + ctx->send_flags = IBV_SEND_SIGNALED; + ctx->rx_depth = rx_depth; + + ctx->buf = memalign(page_size, size); + if (!ctx->buf) { + fprintf(stderr, "Couldn't allocate work buf.\n"); + goto clean_ctx; + } + + /* FIXME memset(ctx->buf, 0, size); */ + memset(ctx->buf, 0x7b, size); + + ctx->context = ibv_open_device(ib_dev); + if (!ctx->context) { + fprintf(stderr, "Couldn't get context for %s\n", + ibv_get_device_name(ib_dev)); + goto clean_buffer; + } + + if (use_event) { + ctx->channel = ibv_create_comp_channel(ctx->context); + if (!ctx->channel) { + fprintf(stderr, "Couldn't create completion channel\n"); + goto clean_device; + } + } else + ctx->channel = NULL; + + ctx->pd = ibv_alloc_pd(ctx->context); + if (!ctx->pd) { + fprintf(stderr, "Couldn't allocate PD\n"); + goto clean_comp_channel; + } + + if (use_odp || use_ts) { + const uint32_t rc_caps_mask = IBV_ODP_SUPPORT_SEND | + IBV_ODP_SUPPORT_RECV; + struct ibv_device_attr_ex attrx; + + if (ibv_query_device_ex(ctx->context, NULL, &attrx)) { + fprintf(stderr, "Couldn't query device for its features\n"); + goto clean_comp_channel; + } + + if (use_odp) { + if (!(attrx.odp_caps.general_caps & IBV_ODP_SUPPORT) || + (attrx.odp_caps.per_transport_caps.rc_odp_caps & rc_caps_mask) != rc_caps_mask) { + fprintf(stderr, "The device isn't ODP capable or does not support RC send and receive with ODP\n"); + goto clean_comp_channel; + } + access_flags |= IBV_ACCESS_ON_DEMAND; + } + + if (use_ts) { + if (!attrx.completion_timestamp_mask) { + fprintf(stderr, "The device isn't completion timestamp capable\n"); + goto clean_comp_channel; + } + ctx->completion_timestamp_mask = attrx.completion_timestamp_mask; + } + } + ctx->mr = ibv_reg_mr(ctx->pd, ctx->buf, size, access_flags); + + if (!ctx->mr) { + fprintf(stderr, "Couldn't register MR\n"); + goto clean_pd; + } + + if (use_ts) { + struct ibv_cq_init_attr_ex attr_ex = { + .cqe = rx_depth + 1, + .cq_context = NULL, + .channel = ctx->channel, + .comp_vector = 0, + .wc_flags = IBV_WC_EX_WITH_COMPLETION_TIMESTAMP + }; + + ctx->cq_s.cq_ex = ibv_create_cq_ex(ctx->context, &attr_ex); + } else { + ctx->cq_s.cq = ibv_create_cq(ctx->context, rx_depth + 1, NULL, + ctx->channel, 0); + } + + if (!pp_cq(ctx)) { + fprintf(stderr, "Couldn't create CQ\n"); + goto clean_mr; + } + + { + struct ibv_qp_attr attr; + struct ibv_qp_init_attr init_attr = { + .send_cq = pp_cq(ctx), + .recv_cq = pp_cq(ctx), + .cap = { + .max_send_wr = 1, + .max_recv_wr = rx_depth, + .max_send_sge = 1, + .max_recv_sge = 1 + }, + .qp_type = IBV_QPT_RC + }; + + ctx->qp = ibv_create_qp(ctx->pd, &init_attr); + if (!ctx->qp) { + fprintf(stderr, "Couldn't create QP\n"); + goto clean_cq; + } + + ibv_query_qp(ctx->qp, &attr, IBV_QP_CAP, &init_attr); + if (init_attr.cap.max_inline_data >= size) { + ctx->send_flags |= IBV_SEND_INLINE; + } + } + + { + struct ibv_qp_attr attr = { + .qp_state = IBV_QPS_INIT, + .pkey_index = 0, + .port_num = port, + .qp_access_flags = 0 + }; + + if (ibv_modify_qp(ctx->qp, &attr, + IBV_QP_STATE | + IBV_QP_PKEY_INDEX | + IBV_QP_PORT | + IBV_QP_ACCESS_FLAGS)) { + fprintf(stderr, "Failed to modify QP to INIT\n"); + goto clean_qp; + } + } + + return ctx; + +clean_qp: + ibv_destroy_qp(ctx->qp); + +clean_cq: + ibv_destroy_cq(pp_cq(ctx)); + +clean_mr: + ibv_dereg_mr(ctx->mr); + +clean_pd: + ibv_dealloc_pd(ctx->pd); + +clean_comp_channel: + if (ctx->channel) + ibv_destroy_comp_channel(ctx->channel); + +clean_device: + ibv_close_device(ctx->context); + +clean_buffer: + free(ctx->buf); + +clean_ctx: + free(ctx); + + return NULL; +} + +static int pp_close_ctx(struct pingpong_context *ctx) +{ + if (ibv_destroy_qp(ctx->qp)) { + fprintf(stderr, "Couldn't destroy QP\n"); + return 1; + } + + if (ibv_destroy_cq(pp_cq(ctx))) { + fprintf(stderr, "Couldn't destroy CQ\n"); + return 1; + } + + if (ibv_dereg_mr(ctx->mr)) { + fprintf(stderr, "Couldn't deregister MR\n"); + return 1; + } + + if (ibv_dealloc_pd(ctx->pd)) { + fprintf(stderr, "Couldn't deallocate PD\n"); + return 1; + } + + if (ctx->channel) { + if (ibv_destroy_comp_channel(ctx->channel)) { + fprintf(stderr, "Couldn't destroy completion channel\n"); + return 1; + } + } + + if (ibv_close_device(ctx->context)) { + fprintf(stderr, "Couldn't release context\n"); + return 1; + } + + free(ctx->buf); + free(ctx); + + return 0; +} + +static int pp_post_recv(struct pingpong_context *ctx, int n) +{ + struct ibv_sge list = { + .addr = (uintptr_t) ctx->buf, + .length = ctx->size, + .lkey = ctx->mr->lkey + }; + struct ibv_recv_wr wr = { + .wr_id = PINGPONG_RECV_WRID, + .sg_list = &list, + .num_sge = 1, + }; + struct ibv_recv_wr *bad_wr; + int i; + + for (i = 0; i < n; ++i) + if (ibv_post_recv(ctx->qp, &wr, &bad_wr)) + break; + + return i; +} + +static int pp_post_send(struct pingpong_context *ctx) +{ + struct ibv_sge list = { + .addr = (uintptr_t) ctx->buf, + .length = ctx->size, + .lkey = ctx->mr->lkey + }; + struct ibv_send_wr wr = { + .wr_id = PINGPONG_SEND_WRID, + .sg_list = &list, + .num_sge = 1, + .opcode = IBV_WR_SEND, + .send_flags = ctx->send_flags, + }; + struct ibv_send_wr *bad_wr; + + return ibv_post_send(ctx->qp, &wr, &bad_wr); +} + +struct ts_params { + uint64_t comp_recv_max_time_delta; + uint64_t comp_recv_min_time_delta; + uint64_t comp_recv_total_time_delta; + uint64_t comp_recv_prev_time; + int last_comp_with_ts; + unsigned int comp_with_time_iters; +}; + +static inline int parse_single_wc(struct pingpong_context *ctx, int *scnt, + int *rcnt, int *routs, int iters, + uint64_t wr_id, enum ibv_wc_status status, + uint64_t completion_timestamp, + struct ts_params *ts) +{ + if (status != IBV_WC_SUCCESS) { + fprintf(stderr, "Failed status %s (%d) for wr_id %d\n", + ibv_wc_status_str(status), + status, (int)wr_id); + return 1; + } + + switch ((int)wr_id) { + case PINGPONG_SEND_WRID: + ++(*scnt); + break; + + case PINGPONG_RECV_WRID: + if (--(*routs) <= 1) { + *routs += pp_post_recv(ctx, ctx->rx_depth - *routs); + if (*routs < ctx->rx_depth) { + fprintf(stderr, + "Couldn't post receive (%d)\n", + *routs); + return 1; + } + } + + ++(*rcnt); + if (use_ts) { + if (ts->last_comp_with_ts) { + uint64_t delta; + + /* checking whether the clock was wrapped around */ + if (completion_timestamp >= ts->comp_recv_prev_time) + delta = completion_timestamp - ts->comp_recv_prev_time; + else + delta = ctx->completion_timestamp_mask - ts->comp_recv_prev_time + + completion_timestamp + 1; + + ts->comp_recv_max_time_delta = max(ts->comp_recv_max_time_delta, delta); + ts->comp_recv_min_time_delta = min(ts->comp_recv_min_time_delta, delta); + ts->comp_recv_total_time_delta += delta; + ts->comp_with_time_iters++; + } + + ts->comp_recv_prev_time = completion_timestamp; + ts->last_comp_with_ts = 1; + } else { + ts->last_comp_with_ts = 0; + } + + break; + + default: + fprintf(stderr, "Completion for unknown wr_id %d\n", + (int)wr_id); + return 1; + } + + ctx->pending &= ~(int)wr_id; + if (*scnt < iters && !ctx->pending) { + if (pp_post_send(ctx)) { + fprintf(stderr, "Couldn't post send\n"); + return 1; + } + ctx->pending = PINGPONG_RECV_WRID | + PINGPONG_SEND_WRID; + } + + return 0; +} + +static void usage(const char *argv0) +{ + printf("Usage:\n"); + printf(" %s start a server and wait for connection\n", argv0); + printf(" %s connect to server at \n", argv0); + printf("\n"); + printf("Options:\n"); + printf(" -p, --port= listen on/connect to port (default 18515)\n"); + printf(" -d, --ib-dev= use IB device (default first device found)\n"); + printf(" -i, --ib-port= use port of IB device (default 1)\n"); + printf(" -s, --size= size of message to exchange (default 4096)\n"); + printf(" -m, --mtu= path MTU (default 1024)\n"); + printf(" -r, --rx-depth= number of receives to post at a time (default 500)\n"); + printf(" -n, --iters= number of exchanges (default 1000)\n"); + printf(" -l, --sl= service level value\n"); + printf(" -e, --events sleep on CQ events (default poll)\n"); + printf(" -g, --gid-idx= local port gid index\n"); + printf(" -o, --odp use on demand paging\n"); + printf(" -t, --ts get CQE with timestamp\n"); + printf(" -c, --chk validate received buffer\n"); +} + +int main(int argc, char *argv[]) +{ + struct ibv_device **dev_list; + struct ibv_device *ib_dev; + struct pingpong_context *ctx; + struct pingpong_dest my_dest; + struct pingpong_dest *rem_dest; + struct timeval start, end; + char *ib_devname = NULL; + char *servername = NULL; + unsigned int port = 18515; + int ib_port = 1; + unsigned int size = 4096; + enum ibv_mtu mtu = IBV_MTU_1024; + unsigned int rx_depth = 500; + unsigned int iters = 1000; + int use_event = 0; + int routs; + int rcnt, scnt; + int num_cq_events = 0; + int sl = 0; + int gidx = -1; + char gid[33]; + struct ts_params ts; + + srand48(getpid() * time(NULL)); + + while (1) { + int c; + + static struct option long_options[] = { + { .name = "port", .has_arg = 1, .val = 'p' }, + { .name = "ib-dev", .has_arg = 1, .val = 'd' }, + { .name = "ib-port", .has_arg = 1, .val = 'i' }, + { .name = "size", .has_arg = 1, .val = 's' }, + { .name = "mtu", .has_arg = 1, .val = 'm' }, + { .name = "rx-depth", .has_arg = 1, .val = 'r' }, + { .name = "iters", .has_arg = 1, .val = 'n' }, + { .name = "sl", .has_arg = 1, .val = 'l' }, + { .name = "events", .has_arg = 0, .val = 'e' }, + { .name = "gid-idx", .has_arg = 1, .val = 'g' }, + { .name = "odp", .has_arg = 0, .val = 'o' }, + { .name = "ts", .has_arg = 0, .val = 't' }, + { .name = "chk", .has_arg = 0, .val = 'c' }, + {} + }; + + c = getopt_long(argc, argv, "p:d:i:s:m:r:n:l:eg:ot:c", + long_options, NULL); + + if (c == -1) + break; + + switch (c) { + case 'p': + port = strtoul(optarg, NULL, 0); + if (port > 65535) { + usage(argv[0]); + return 1; + } + break; + + case 'd': + ib_devname = strdupa(optarg); + break; + + case 'i': + ib_port = strtol(optarg, NULL, 0); + if (ib_port < 1) { + usage(argv[0]); + return 1; + } + break; + + case 's': + size = strtoul(optarg, NULL, 0); + break; + + case 'm': + mtu = pp_mtu_to_enum(strtol(optarg, NULL, 0)); + if (mtu == 0) { + usage(argv[0]); + return 1; + } + break; + + case 'r': + rx_depth = strtoul(optarg, NULL, 0); + break; + + case 'n': + iters = strtoul(optarg, NULL, 0); + break; + + case 'l': + sl = strtol(optarg, NULL, 0); + break; + + case 'e': + ++use_event; + break; + + case 'g': + gidx = strtol(optarg, NULL, 0); + break; + + case 'o': + use_odp = 1; + break; + case 't': + use_ts = 1; + break; + case 'c': + validate_buf = 1; + break; + + default: + usage(argv[0]); + return 1; + } + } + + if (optind == argc - 1) + servername = strdupa(argv[optind]); + else if (optind < argc) { + usage(argv[0]); + return 1; + } + + if (use_ts) { + ts.comp_recv_max_time_delta = 0; + ts.comp_recv_min_time_delta = 0xffffffff; + ts.comp_recv_total_time_delta = 0; + ts.comp_recv_prev_time = 0; + ts.last_comp_with_ts = 0; + ts.comp_with_time_iters = 0; + } + + page_size = sysconf(_SC_PAGESIZE); + + dev_list = ibv_get_device_list(NULL); + if (!dev_list) { + perror("Failed to get IB devices list"); + return 1; + } + + if (!ib_devname) { + ib_dev = *dev_list; + if (!ib_dev) { + fprintf(stderr, "No IB devices found\n"); + return 1; + } + } else { + int i; + for (i = 0; dev_list[i]; ++i) + if (!strcmp(ibv_get_device_name(dev_list[i]), ib_devname)) + break; + ib_dev = dev_list[i]; + if (!ib_dev) { + fprintf(stderr, "IB device %s not found\n", ib_devname); + return 1; + } + } + + ctx = pp_init_ctx(ib_dev, size, rx_depth, ib_port, use_event); + if (!ctx) + return 1; + + routs = pp_post_recv(ctx, ctx->rx_depth); + if (routs < ctx->rx_depth) { + fprintf(stderr, "Couldn't post receive (%d)\n", routs); + return 1; + } + + if (use_event) + if (ibv_req_notify_cq(pp_cq(ctx), 0)) { + fprintf(stderr, "Couldn't request CQ notification\n"); + return 1; + } + + + if (pp_get_port_info(ctx->context, ib_port, &ctx->portinfo)) { + fprintf(stderr, "Couldn't get port info\n"); + return 1; + } + + my_dest.lid = ctx->portinfo.lid; + if (ctx->portinfo.link_layer != IBV_LINK_LAYER_ETHERNET && + !my_dest.lid) { + fprintf(stderr, "Couldn't get local LID\n"); + return 1; + } + + if (gidx >= 0) { + if (ibv_query_gid(ctx->context, ib_port, gidx, &my_dest.gid)) { + fprintf(stderr, "can't read sgid of index %d\n", gidx); + return 1; + } + } else + memset(&my_dest.gid, 0, sizeof my_dest.gid); + + my_dest.qpn = ctx->qp->qp_num; + my_dest.psn = lrand48() & 0xffffff; + /* inet_ntop(AF_INET6, &my_dest.gid, gid, sizeof gid); */ + /* printf(" local address: LID 0x%04x, QPN 0x%06x, PSN 0x%06x, GID %s\n", */ + /* my_dest.lid, my_dest.qpn, my_dest.psn, gid); */ + + + if (servername) + rem_dest = pp_client_exch_dest(servername, port, &my_dest); + else + rem_dest = pp_server_exch_dest(ctx, ib_port, mtu, port, sl, + &my_dest, gidx); + + if (!rem_dest) + return 1; + + /* inet_ntop(AF_INET6, &rem_dest->gid, gid, sizeof gid); */ + /* printf(" remote address: LID 0x%04x, QPN 0x%06x, PSN 0x%06x, GID %s\n", */ + /* rem_dest->lid, rem_dest->qpn, rem_dest->psn, gid); */ + + if (servername) + if (pp_connect_ctx(ctx, ib_port, my_dest.psn, mtu, sl, rem_dest, + gidx)) + return 1; + + ctx->pending = PINGPONG_RECV_WRID; + + if (servername) { + if (validate_buf) + for (int i = 0; i < size; i += page_size) + ctx->buf[i] = i / page_size % sizeof(char); + if (pp_post_send(ctx)) { + fprintf(stderr, "Couldn't post send\n"); + return 1; + } + ctx->pending |= PINGPONG_SEND_WRID; + } + + if (gettimeofday(&start, NULL)) { + perror("gettimeofday"); + return 1; + } + + rcnt = scnt = 0; + while (rcnt < iters || scnt < iters) { + int ret; + + if (use_event) { + struct ibv_cq *ev_cq; + void *ev_ctx; + + if (ibv_get_cq_event(ctx->channel, &ev_cq, &ev_ctx)) { + fprintf(stderr, "Failed to get cq_event\n"); + return 1; + } + + ++num_cq_events; + + if (ev_cq != pp_cq(ctx)) { + fprintf(stderr, "CQ event for unknown CQ %p\n", ev_cq); + return 1; + } + + if (ibv_req_notify_cq(pp_cq(ctx), 0)) { + fprintf(stderr, "Couldn't request CQ notification\n"); + return 1; + } + } + + if (use_ts) { + struct ibv_poll_cq_attr attr = {}; + + do { + ret = ibv_start_poll(ctx->cq_s.cq_ex, &attr); + } while (!use_event && ret == ENOENT); + + if (ret) { + fprintf(stderr, "poll CQ failed %d\n", ret); + return ret; + } + ret = parse_single_wc(ctx, &scnt, &rcnt, &routs, + iters, + ctx->cq_s.cq_ex->wr_id, + ctx->cq_s.cq_ex->status, + ibv_wc_read_completion_ts(ctx->cq_s.cq_ex), + &ts); + if (ret) { + ibv_end_poll(ctx->cq_s.cq_ex); + return ret; + } + ret = ibv_next_poll(ctx->cq_s.cq_ex); + if (!ret) + ret = parse_single_wc(ctx, &scnt, &rcnt, &routs, + iters, + ctx->cq_s.cq_ex->wr_id, + ctx->cq_s.cq_ex->status, + ibv_wc_read_completion_ts(ctx->cq_s.cq_ex), + &ts); + ibv_end_poll(ctx->cq_s.cq_ex); + if (ret && ret != ENOENT) { + fprintf(stderr, "poll CQ failed %d\n", ret); + return ret; + } + } else { + int ne, i; + struct ibv_wc wc[2]; + + do { + ne = ibv_poll_cq(pp_cq(ctx), 2, wc); + if (ne < 0) { + fprintf(stderr, "poll CQ failed %d\n", ne); + return 1; + } + } while (!use_event && ne < 1); + + for (i = 0; i < ne; ++i) { + ret = parse_single_wc(ctx, &scnt, &rcnt, &routs, + iters, + wc[i].wr_id, + wc[i].status, + 0, &ts); + if (ret) { + fprintf(stderr, "parse WC failed %d\n", ne); + return 1; + } + } + } + } + + if (gettimeofday(&end, NULL)) { + perror("gettimeofday"); + return 1; + } + + { + float usec = (end.tv_sec - start.tv_sec) * 1000000 + + (end.tv_usec - start.tv_usec); + long long bytes = (long long) size * iters * 2; + + printf("%lld bytes in %.2f seconds = %.2f Mbit/sec\n", + bytes, usec / 1000000., bytes * 8. / usec); + printf("%d iters in %.2f seconds = %.2f usec/iter\n", + iters, usec / 1000000., usec / iters); + + if (use_ts && ts.comp_with_time_iters) { + printf("Max receive completion clock cycles = %" PRIu64 "\n", + ts.comp_recv_max_time_delta); + printf("Min receive completion clock cycles = %" PRIu64 "\n", + ts.comp_recv_min_time_delta); + printf("Average receive completion clock cycles = %f\n", + (double)ts.comp_recv_total_time_delta / ts.comp_with_time_iters); + } + + if ((!servername) && (validate_buf)) { + for (int i = 0; i < size; i += page_size) + if (ctx->buf[i] != i / page_size % sizeof(char)) + printf("invalid data in page %d\n", + i / page_size); + } + } + + ibv_ack_cq_events(pp_cq(ctx), num_cq_events); + + if (pp_close_ctx(ctx)) + return 1; + + ibv_free_device_list(dev_list); + free(rem_dest); + + return 0; +} diff --git a/usr/tests/ib/pingpong-ud.c b/usr/tests/ib/pingpong-ud.c index 9c8621f60..708823012 100644 --- a/usr/tests/ib/pingpong-ud.c +++ b/usr/tests/ib/pingpong-ud.c @@ -504,28 +504,30 @@ static int pp_close_ctx(struct pingpong_context *ctx) return 0; } -static int pp_post_recv(struct pingpong_context *ctx, int n) +static int pp_post_recv(struct pingpong_context *ctx, int rx_depth) { - /* printf("Entered pp_post_recv().\n"); */ - struct ibv_sge list = { - .addr = (uintptr_t) ctx->buf, - .length = ctx->size + 40, - /* .lkey = ctx->mr->lkey */ - .lkey = ibv_get_mr_lkey(ctx->mr) - }; - struct ibv_recv_wr wr = { - .wr_id = PINGPONG_RECV_WRID, - .sg_list = &list, - .num_sge = 1, - }; - struct ibv_recv_wr *bad_wr; + printf("Entered pp_post_recv().\n"); int i; - for (i = 0; i < n; ++i) { + for (i = 0; i < rx_depth; ++i) { + struct ibv_sge list = { + .addr = (uintptr_t) ctx->buf, + .length = ctx->size + 40, + /* .lkey = ctx->mr->lkey */ + .lkey = ibv_get_mr_lkey(ctx->mr) // ! + }; + struct ibv_recv_wr wr = { + .wr_id = PINGPONG_RECV_WRID, + .sg_list = &list, + .num_sge = 1, + }; + struct ibv_recv_wr *bad_wr; + if (ibv_post_recv(ctx->qp, &wr, &bad_wr)) break; } + printf("Finished pp_post_recv().\n"); return i; } @@ -587,7 +589,7 @@ int main(int argc, char *argv[]) unsigned int port = 18515; int ib_port = 1; unsigned int size = 2048; - unsigned int rx_depth = 500; + unsigned int rx_depth = 1; unsigned int iters = 1000; int use_event = 0; int routs;