From 60a3537b3580433defff353eb7e97f6b1c23b4eb Mon Sep 17 00:00:00 2001 From: Sean Hefty Date: Tue, 23 Oct 2012 00:59:59 -0700 Subject: [PATCH] refresh --- meta | 7 +- patches/refresh-temp | 322 ------------------------------------------- patches/rs-iomap | 314 ++++++++++++++++++++++++++++++++++++++--- 3 files changed, 297 insertions(+), 346 deletions(-) delete mode 100644 patches/refresh-temp diff --git a/meta b/meta index 20ab6639..0a7f3a4b 100644 --- a/meta +++ b/meta @@ -1,9 +1,8 @@ Version: 1 -Previous: d2b0428f8aa4a167a53833682c818422982dfe2e -Head: f0fc707aeebfbb6b383d6d5d471310e2a46a004b +Previous: 747ba387f3231c37084d5b777baa771386af7b08 +Head: c25bf6431d76aca86ee4bf93d71a319fe3096a83 Applied: - rs-iomap: 4507f7d7d64e24375de21367e59a39665d85e12b - refresh-temp: f0fc707aeebfbb6b383d6d5d471310e2a46a004b + rs-iomap: c25bf6431d76aca86ee4bf93d71a319fe3096a83 Unapplied: resv-rs-len: 7b6ff5c4894f54b221d877adcd709795dffb2fe9 rs-target-sgl: 7a07c80f2242e80c076dcf3ec6bb4c94626b284f diff --git a/patches/refresh-temp b/patches/refresh-temp deleted file mode 100644 index 71003f0d..00000000 --- a/patches/refresh-temp +++ /dev/null @@ -1,322 +0,0 @@ -Bottom: 5604b4bc827008a75c9690ec7b8ff3cc77314374 -Top: ea70904deb6e6424cbdeacc9a46e20ee1b29e5c0 -Author: Sean Hefty -Date: 2012-10-23 00:59:59 -0700 - -Refresh of rs-iomap - ---- - -diff --git a/include/rdma/rsocket.h b/include/rdma/rsocket.h -index 65feda9..21477e4 100644 ---- a/include/rdma/rsocket.h -+++ b/include/rdma/rsocket.h -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2011 Intel Corporation. All rights reserved. -+ * Copyright (c) 2011-2012 Intel Corporation. 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 -@@ -85,6 +85,10 @@ int rgetsockopt(int socket, int level, int optname, - void *optval, socklen_t *optlen); - int rfcntl(int socket, int cmd, ... /* arg */ ); - -+off_t riomap(int socket, void *buf, size_t len, int prot, int flags, off_t offset); -+int riounmap(int socket, void *buf, size_t len); -+size_t riowrite(int socket, const void *buf, size_t count, off_t offset, int flags); -+ - #ifdef __cplusplus - } - #endif -diff --git a/src/indexer.h b/src/indexer.h -index 26e7f98..0c5f388 100644 ---- a/src/indexer.h -+++ b/src/indexer.h -@@ -31,6 +31,9 @@ - * - */ - -+#if !defined(INDEXER_H) -+#define INDEXER_H -+ - #if HAVE_CONFIG_H - # include - #endif /* HAVE_CONFIG_H */ -@@ -99,3 +102,43 @@ static inline void *idm_lookup(struct index_map *idm, int index) - return ((index <= IDX_MAX_INDEX) && idm->array[idx_array_index(index)]) ? - idm_at(idm, index) : NULL; - } -+ -+typedef struct _dlist_entry { -+ struct _dlist_entry *next; -+ struct _dlist_entry *prev; -+} dlist_entry; -+ -+static inline void dlist_init(dlist_entry *head) -+{ -+ head->next = head; -+ head->prev = head; -+} -+ -+static inline int dlist_empty(dlist_entry *head) -+{ -+ return head->next == head; -+} -+ -+static inline void dlist_insert_after(dlist_entry *item, dlist_entry *head) -+{ -+ item->next = head->next; -+ item->prev = head; -+ head->next->prev = item; -+ head->next = item; -+} -+ -+static inline void dlist_insert_before(dlist_entry *item, dlist_entry *head) -+{ -+ dlist_insert_after(item, head->prev); -+} -+ -+#define dlist_insert_head dlist_insert_after -+#define dlist_insert_tail dlist_insert_before -+ -+static inline void dlist_remove(dlist_entry *item) -+{ -+ item->prev->next = item->next; -+ item->next->prev = item->prev; -+} -+ -+#endif /* INDEXER_H */ -diff --git a/src/rsocket.c b/src/rsocket.c -index 40d9440..ed708d4 100644 ---- a/src/rsocket.c -+++ b/src/rsocket.c -@@ -59,7 +59,6 @@ - #define RS_QP_CTRL_SIZE 4 - #define RS_CONN_RETRIES 6 - #define RS_SGL_SIZE 2 --#define RS_MAX_IOMAP 128 - static struct index_map idm; - static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; - -@@ -118,6 +117,14 @@ struct rs_iomap { - struct rs_sge sge; - }; - -+struct rs_iomap_mr { -+ uint64_t offset; -+ struct ibv_mr *mr; -+ dlist_entry entry; -+ atomic_t refcnt; -+ int index; /* -1 if mapping is local and not in iomap_list */ -+}; -+ - #define RS_MIN_INLINE (sizeof(struct rs_sge)) - #define rs_host_is_net() (1 == htonl(1)) - #define RS_CONN_FLAG_NET (1 << 0) -@@ -164,6 +171,7 @@ struct rsocket { - fastlock_t rlock; - fastlock_t cq_lock; - fastlock_t cq_wait_lock; -+ fastlock_t iomap_lock; - - int opts; - long fd_flags; -@@ -196,7 +204,11 @@ struct rsocket { - int remote_sge; - struct rs_sge remote_sgl; - struct rs_sge remote_iomap; -- struct rs_iomap *remote_iomappings; -+ -+ struct rs_iomap_mr *remote_iomappings; -+ dlist_entry iomap_list; -+ dlist_entry iomap_queue; -+ int iomap_pending; - - struct ibv_mr *target_mr; - int target_sge; -@@ -336,6 +348,9 @@ static struct rsocket *rs_alloc(struct rsocket *inherited_rs) - fastlock_init(&rs->rlock); - fastlock_init(&rs->cq_lock); - fastlock_init(&rs->cq_wait_lock); -+ fastlock_init(&rs->iomap_lock); -+ dlist_init(&rs->iomap_list); -+ dlist_init(&rs->iomap_queue); - return rs; - } - -@@ -501,6 +516,42 @@ static int rs_create_ep(struct rsocket *rs) - return 0; - } - -+/* -+static xxx rs_acquire_iomap_mr(struct rsocket *rs, ...) -+{ -+ TODO: write me -+} -+*/ -+ -+static void rs_release_iomap_mr(struct rs_iomap_mr *iomr) -+{ -+ if (atomic_dec(&iomr->refcnt)) -+ return; -+ -+ dlist_remove(&iomr->entry); -+ ibv_dereg_mr(iomr->mr); -+ if (iomr->index >= 0) -+ iomr->mr = NULL; -+ else -+ free(iomr); -+} -+ -+static void rs_free_iomappings(struct rsocket *rs) -+{ -+ struct rs_iomap_mr *iomr; -+ -+ while (!dlist_empty(&rs->iomap_list)) { -+ iomr = container_of(rs->iomap_list.next, -+ struct rs_iomap_mr, entry); -+ riounmap(iomr->mr->addr, iomr->mr->length); -+ } -+ while (!dlist_empty(&rs->iomap_queue)) { -+ iomr = container_of(rs->iomap_queue.next, -+ struct rs_iomap_mr, entry); -+ riounmap(iomr->mr->addr, iomr->mr->length); -+ } -+} -+ - static void rs_free(struct rsocket *rs) - { - if (rs->index >= 0) -@@ -528,11 +579,13 @@ static void rs_free(struct rsocket *rs) - } - - if (rs->cm_id) { -+ rs_free_iomappings(rs); - if (rs->cm_id->qp) - rdma_destroy_qp(rs->cm_id); - rdma_destroy_id(rs->cm_id); - } - -+ fastlock_destroy(&rs->iomap_lock); - fastlock_destroy(&rs->cq_wait_lock); - fastlock_destroy(&rs->cq_lock); - fastlock_destroy(&rs->rlock); -@@ -2081,3 +2134,117 @@ int rfcntl(int socket, int cmd, ... /* arg */ ) - va_end(args); - return ret; - } -+ -+static struct rs_iomap_mr *rs_get_iomap_mr(struct rsocket *rs) -+{ -+ struct rs_iomap_mr *iomr; -+ int i; -+ -+ if (!rs->remote_iomappings) { -+ rs->remote_iomappings = calloc(rs->remote_iomap.length, -+ sizeof(*rs->remote_iomappings)); -+ if (!rs->remote_iomappings) -+ return NULL; -+ -+ for (i = 0; i < rs->remote_iomap.length; i++) -+ rs->remote_iomappings[i].index = i; -+ } -+ -+ for (i = 0; i < rs->remote_iomap.length; i++) { -+ if (!rs->remote_iomappings[i]->mr) -+ return &rs->remote_iomappings[i]; -+ } -+ return NULL; -+} -+ -+/* -+ * If an offset is given, we map to it. If offset is -1, then we map the -+ * offset to the address of buf. We do not check for conflicts, which must -+ * be fixed at some point. -+ */ -+off_t riomap(int socket, void *buf, size_t len, int prot, int flags, off_t offset) -+{ -+ struct rsocket *rs; -+ struct rs_iomap_mr *iomr; -+ int ret, access = IBV_ACCESS_LOCAL_WRITE; -+ -+ rs = idm_at(&idm, socket); -+ if ((rs->state != rs_connect_rdwr) || (prot & ~(PROT_WRITE | PROT_NONE))) -+ return ERR(EINVAL); -+ -+ fastlock_acquire(&rs->iomap_lock); -+ if (prot & PROT_WRITE) { -+ iomr = rs_get_iomap_mr(rs); -+ access |= IBV_ACCESS_REMOTE_WRITE; -+ } else { -+ iomr = calloc(1, sizeof *iomr); -+ iomr->index = -1; -+ } -+ if (!iomr) { -+ offset = ERR(ENOMEM); -+ goto out; -+ } -+ -+ iomr->mr = ibv_reg_mr(rs->cm_id->pd, buf, len, access); -+ if (!iomr->mr) { -+ if (iomr->index < 0) -+ free(iomr); -+ offset = -1; -+ goto out; -+ } -+ -+ if (offset == -1) -+ offset = (uintptr_t) buf; -+ iomr->offset = offset; -+ iomr->prot = prot; -+ atomic_init(&iomr->refcnt); -+ atomic_set(&iomr->refcnt, 1); -+ -+ if (iomr->index >= 0) { -+ dlist_insert_tail(&iomr->entry, &rs->iomap_queue); -+ rs->iomap_pending = 1; -+ } else { -+ dlist_insert_tail(&iomr->entry, &rs->iomap_list); -+ } -+out: -+ fastlock_release(&rs->iomap_lock); -+ return offset; -+} -+ -+int riounmap(int socket, void *buf, size_t len) -+{ -+ struct rsocket *rs; -+ struct rs_iomap_mr *iomr; -+ struct dlist_entry *entry; -+ int ret = 0; -+ -+ rs = idm_at(&idm, socket); -+ fastlock_acquire(&rs->iomap_lock); -+ -+ for (entry = rs->iomap_list.next; entry != &rs->iomap_list; -+ entry = entry->next) { -+ iomr = container_of(entry, struct rs_iomap_mr, entry); -+ if (iomr->mr->addr == buf && iomr->mr->length == len) { -+ rs_release_iomap_mr(iomr); -+ goto out; -+ } -+ } -+ -+ for (entry = rs->iomap_queue.next; entry != &rs->iomap_queue; -+ entry = entry->next) { -+ iomr = container_of(entry, struct rs_iomap_mr, entry); -+ if (iomr->mr->addr == buf && iomr->mr->length == len) { -+ rs_release_iomap_mr(iomr); -+ goto out; -+ } -+ } -+ ret = ERR(EINVAL); -+out: -+ fastlock_release(&rs->iomap_lock); -+ return ret; -+} -+ -+size_t riowrite(int socket, const void *buf, size_t count, off_t offset, int flags) -+{ -+ -+} diff --git a/patches/rs-iomap b/patches/rs-iomap index cdbf1158..7dc0c1c3 100644 --- a/patches/rs-iomap +++ b/patches/rs-iomap @@ -1,5 +1,5 @@ Bottom: daf53db464152f40dc8d6f2c99844510b03f8567 -Top: 5604b4bc827008a75c9690ec7b8ff3cc77314374 +Top: ea70904deb6e6424cbdeacc9a46e20ee1b29e5c0 Author: Sean Hefty Date: 2012-10-21 14:16:03 -0700 @@ -10,15 +10,91 @@ Signed-off-by: Sean Hefty --- +diff --git a/include/rdma/rsocket.h b/include/rdma/rsocket.h +index 65feda9..21477e4 100644 +--- a/include/rdma/rsocket.h ++++ b/include/rdma/rsocket.h +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2011 Intel Corporation. All rights reserved. ++ * Copyright (c) 2011-2012 Intel Corporation. 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 +@@ -85,6 +85,10 @@ int rgetsockopt(int socket, int level, int optname, + void *optval, socklen_t *optlen); + int rfcntl(int socket, int cmd, ... /* arg */ ); + ++off_t riomap(int socket, void *buf, size_t len, int prot, int flags, off_t offset); ++int riounmap(int socket, void *buf, size_t len); ++size_t riowrite(int socket, const void *buf, size_t count, off_t offset, int flags); ++ + #ifdef __cplusplus + } + #endif +diff --git a/src/indexer.h b/src/indexer.h +index 26e7f98..0c5f388 100644 +--- a/src/indexer.h ++++ b/src/indexer.h +@@ -31,6 +31,9 @@ + * + */ + ++#if !defined(INDEXER_H) ++#define INDEXER_H ++ + #if HAVE_CONFIG_H + # include + #endif /* HAVE_CONFIG_H */ +@@ -99,3 +102,43 @@ static inline void *idm_lookup(struct index_map *idm, int index) + return ((index <= IDX_MAX_INDEX) && idm->array[idx_array_index(index)]) ? + idm_at(idm, index) : NULL; + } ++ ++typedef struct _dlist_entry { ++ struct _dlist_entry *next; ++ struct _dlist_entry *prev; ++} dlist_entry; ++ ++static inline void dlist_init(dlist_entry *head) ++{ ++ head->next = head; ++ head->prev = head; ++} ++ ++static inline int dlist_empty(dlist_entry *head) ++{ ++ return head->next == head; ++} ++ ++static inline void dlist_insert_after(dlist_entry *item, dlist_entry *head) ++{ ++ item->next = head->next; ++ item->prev = head; ++ head->next->prev = item; ++ head->next = item; ++} ++ ++static inline void dlist_insert_before(dlist_entry *item, dlist_entry *head) ++{ ++ dlist_insert_after(item, head->prev); ++} ++ ++#define dlist_insert_head dlist_insert_after ++#define dlist_insert_tail dlist_insert_before ++ ++static inline void dlist_remove(dlist_entry *item) ++{ ++ item->prev->next = item->next; ++ item->next->prev = item->prev; ++} ++ ++#endif /* INDEXER_H */ diff --git a/src/rsocket.c b/src/rsocket.c -index cc5effe..40d9440 100644 +index cc5effe..ed708d4 100644 --- a/src/rsocket.c +++ b/src/rsocket.c -@@ -59,9 +59,11 @@ - #define RS_QP_CTRL_SIZE 4 - #define RS_CONN_RETRIES 6 - #define RS_SGL_SIZE 2 -+#define RS_MAX_IOMAP 128 +@@ -62,6 +62,7 @@ static struct index_map idm; static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; @@ -26,7 +102,7 @@ index cc5effe..40d9440 100644 static uint16_t def_inline = 64; static uint16_t def_sqsize = 384; static uint16_t def_rqsize = 384; -@@ -76,7 +78,7 @@ static uint32_t polling_time = 10; +@@ -76,7 +77,7 @@ static uint32_t polling_time = 10; * bit 29: more data, 0 - end of transfer, 1 - more data available * * for data transfers: @@ -35,7 +111,7 @@ index cc5effe..40d9440 100644 * for control messages: * bits [28-0]: receive credits granted */ -@@ -111,15 +113,22 @@ struct rs_sge { +@@ -111,15 +112,30 @@ struct rs_sge { uint32_t length; }; @@ -47,6 +123,14 @@ index cc5effe..40d9440 100644 + struct rs_sge sge; +}; + ++struct rs_iomap_mr { ++ uint64_t offset; ++ struct ibv_mr *mr; ++ dlist_entry entry; ++ atomic_t refcnt; ++ int index; /* -1 if mapping is local and not in iomap_list */ ++}; ++ +#define RS_MIN_INLINE (sizeof(struct rs_sge)) +#define rs_host_is_net() (1 == htonl(1)) +#define RS_CONN_FLAG_NET (1 << 0) @@ -62,12 +146,24 @@ index cc5effe..40d9440 100644 struct rs_sge target_sgl; struct rs_sge data_buf; }; -@@ -186,10 +195,15 @@ struct rsocket { +@@ -155,6 +171,7 @@ struct rsocket { + fastlock_t rlock; + fastlock_t cq_lock; + fastlock_t cq_wait_lock; ++ fastlock_t iomap_lock; + + int opts; + long fd_flags; +@@ -186,10 +203,19 @@ struct rsocket { int remote_sge; struct rs_sge remote_sgl; + struct rs_sge remote_iomap; -+ struct rs_iomap *remote_iomappings; ++ ++ struct rs_iomap_mr *remote_iomappings; ++ dlist_entry iomap_list; ++ dlist_entry iomap_queue; ++ int iomap_pending; struct ibv_mr *target_mr; int target_sge; @@ -79,7 +175,7 @@ index cc5effe..40d9440 100644 uint32_t rbuf_size; struct ibv_mr *rmr; -@@ -201,6 +215,18 @@ struct rsocket { +@@ -201,6 +227,18 @@ struct rsocket { uint8_t *sbuf; }; @@ -98,7 +194,7 @@ index cc5effe..40d9440 100644 void rs_configure(void) { FILE *f; -@@ -251,6 +277,15 @@ void rs_configure(void) +@@ -251,6 +289,15 @@ void rs_configure(void) if (def_wmem < 1) def_wmem = 1; } @@ -114,7 +210,7 @@ index cc5effe..40d9440 100644 init = 1; out: pthread_mutex_unlock(&mut); -@@ -287,6 +322,7 @@ static struct rsocket *rs_alloc(struct rsocket *inherited_rs) +@@ -287,6 +334,7 @@ static struct rsocket *rs_alloc(struct rsocket *inherited_rs) rs->sq_size = inherited_rs->sq_size; rs->rq_size = inherited_rs->rq_size; rs->ctrl_avail = inherited_rs->ctrl_avail; @@ -122,7 +218,7 @@ index cc5effe..40d9440 100644 } else { rs->sbuf_size = def_wmem; rs->rbuf_size = def_mem; -@@ -294,6 +330,7 @@ static struct rsocket *rs_alloc(struct rsocket *inherited_rs) +@@ -294,11 +342,15 @@ static struct rsocket *rs_alloc(struct rsocket *inherited_rs) rs->sq_size = def_sqsize; rs->rq_size = def_rqsize; rs->ctrl_avail = RS_QP_CTRL_SIZE; @@ -130,7 +226,15 @@ index cc5effe..40d9440 100644 } fastlock_init(&rs->slock); fastlock_init(&rs->rlock); -@@ -336,6 +373,8 @@ static void rs_set_qp_size(struct rsocket *rs) + fastlock_init(&rs->cq_lock); + fastlock_init(&rs->cq_wait_lock); ++ fastlock_init(&rs->iomap_lock); ++ dlist_init(&rs->iomap_list); ++ dlist_init(&rs->iomap_queue); + return rs; + } + +@@ -336,6 +388,8 @@ static void rs_set_qp_size(struct rsocket *rs) static int rs_init_bufs(struct rsocket *rs) { @@ -139,7 +243,7 @@ index cc5effe..40d9440 100644 rs->rmsg = calloc(rs->rq_size + 1, sizeof(*rs->rmsg)); if (!rs->rmsg) return -1; -@@ -348,11 +387,21 @@ static int rs_init_bufs(struct rsocket *rs) +@@ -348,11 +402,21 @@ static int rs_init_bufs(struct rsocket *rs) if (!rs->smr) return -1; @@ -163,7 +267,50 @@ index cc5effe..40d9440 100644 rs->rbuf = calloc(rs->rbuf_size, sizeof(*rs->rbuf)); if (!rs->rbuf) return -1; -@@ -472,8 +521,11 @@ static void rs_free(struct rsocket *rs) +@@ -452,6 +516,42 @@ static int rs_create_ep(struct rsocket *rs) + return 0; + } + ++/* ++static xxx rs_acquire_iomap_mr(struct rsocket *rs, ...) ++{ ++ TODO: write me ++} ++*/ ++ ++static void rs_release_iomap_mr(struct rs_iomap_mr *iomr) ++{ ++ if (atomic_dec(&iomr->refcnt)) ++ return; ++ ++ dlist_remove(&iomr->entry); ++ ibv_dereg_mr(iomr->mr); ++ if (iomr->index >= 0) ++ iomr->mr = NULL; ++ else ++ free(iomr); ++} ++ ++static void rs_free_iomappings(struct rsocket *rs) ++{ ++ struct rs_iomap_mr *iomr; ++ ++ while (!dlist_empty(&rs->iomap_list)) { ++ iomr = container_of(rs->iomap_list.next, ++ struct rs_iomap_mr, entry); ++ riounmap(iomr->mr->addr, iomr->mr->length); ++ } ++ while (!dlist_empty(&rs->iomap_queue)) { ++ iomr = container_of(rs->iomap_queue.next, ++ struct rs_iomap_mr, entry); ++ riounmap(iomr->mr->addr, iomr->mr->length); ++ } ++} ++ + static void rs_free(struct rsocket *rs) + { + if (rs->index >= 0) +@@ -472,15 +572,20 @@ static void rs_free(struct rsocket *rs) free(rs->rbuf); } @@ -176,8 +323,17 @@ index cc5effe..40d9440 100644 + } if (rs->cm_id) { ++ rs_free_iomappings(rs); if (rs->cm_id->qp) -@@ -492,9 +544,11 @@ static void rs_set_conn_data(struct rsocket *rs, struct rdma_conn_param *param, + rdma_destroy_qp(rs->cm_id); + rdma_destroy_id(rs->cm_id); + } + ++ fastlock_destroy(&rs->iomap_lock); + fastlock_destroy(&rs->cq_wait_lock); + fastlock_destroy(&rs->cq_lock); + fastlock_destroy(&rs->rlock); +@@ -492,9 +597,11 @@ static void rs_set_conn_data(struct rsocket *rs, struct rdma_conn_param *param, struct rs_conn_data *conn) { conn->version = 1; @@ -191,7 +347,7 @@ index cc5effe..40d9440 100644 conn->target_sgl.addr = htonll((uintptr_t) rs->target_sgl); conn->target_sgl.length = htonl(RS_SGL_SIZE); -@@ -518,6 +572,13 @@ static void rs_save_conn_data(struct rsocket *rs, struct rs_conn_data *conn) +@@ -518,6 +625,13 @@ static void rs_save_conn_data(struct rsocket *rs, struct rs_conn_data *conn) (!rs_host_is_net() && (conn->flags & RS_CONN_FLAG_NET))) rs->opts = RS_OPT_SWAP_SGL; @@ -205,3 +361,121 @@ index cc5effe..40d9440 100644 rs->target_sgl[0].addr = ntohll(conn->data_buf.addr); rs->target_sgl[0].length = ntohl(conn->data_buf.length); rs->target_sgl[0].key = ntohl(conn->data_buf.key); +@@ -2020,3 +2134,117 @@ int rfcntl(int socket, int cmd, ... /* arg */ ) + va_end(args); + return ret; + } ++ ++static struct rs_iomap_mr *rs_get_iomap_mr(struct rsocket *rs) ++{ ++ struct rs_iomap_mr *iomr; ++ int i; ++ ++ if (!rs->remote_iomappings) { ++ rs->remote_iomappings = calloc(rs->remote_iomap.length, ++ sizeof(*rs->remote_iomappings)); ++ if (!rs->remote_iomappings) ++ return NULL; ++ ++ for (i = 0; i < rs->remote_iomap.length; i++) ++ rs->remote_iomappings[i].index = i; ++ } ++ ++ for (i = 0; i < rs->remote_iomap.length; i++) { ++ if (!rs->remote_iomappings[i]->mr) ++ return &rs->remote_iomappings[i]; ++ } ++ return NULL; ++} ++ ++/* ++ * If an offset is given, we map to it. If offset is -1, then we map the ++ * offset to the address of buf. We do not check for conflicts, which must ++ * be fixed at some point. ++ */ ++off_t riomap(int socket, void *buf, size_t len, int prot, int flags, off_t offset) ++{ ++ struct rsocket *rs; ++ struct rs_iomap_mr *iomr; ++ int ret, access = IBV_ACCESS_LOCAL_WRITE; ++ ++ rs = idm_at(&idm, socket); ++ if ((rs->state != rs_connect_rdwr) || (prot & ~(PROT_WRITE | PROT_NONE))) ++ return ERR(EINVAL); ++ ++ fastlock_acquire(&rs->iomap_lock); ++ if (prot & PROT_WRITE) { ++ iomr = rs_get_iomap_mr(rs); ++ access |= IBV_ACCESS_REMOTE_WRITE; ++ } else { ++ iomr = calloc(1, sizeof *iomr); ++ iomr->index = -1; ++ } ++ if (!iomr) { ++ offset = ERR(ENOMEM); ++ goto out; ++ } ++ ++ iomr->mr = ibv_reg_mr(rs->cm_id->pd, buf, len, access); ++ if (!iomr->mr) { ++ if (iomr->index < 0) ++ free(iomr); ++ offset = -1; ++ goto out; ++ } ++ ++ if (offset == -1) ++ offset = (uintptr_t) buf; ++ iomr->offset = offset; ++ iomr->prot = prot; ++ atomic_init(&iomr->refcnt); ++ atomic_set(&iomr->refcnt, 1); ++ ++ if (iomr->index >= 0) { ++ dlist_insert_tail(&iomr->entry, &rs->iomap_queue); ++ rs->iomap_pending = 1; ++ } else { ++ dlist_insert_tail(&iomr->entry, &rs->iomap_list); ++ } ++out: ++ fastlock_release(&rs->iomap_lock); ++ return offset; ++} ++ ++int riounmap(int socket, void *buf, size_t len) ++{ ++ struct rsocket *rs; ++ struct rs_iomap_mr *iomr; ++ struct dlist_entry *entry; ++ int ret = 0; ++ ++ rs = idm_at(&idm, socket); ++ fastlock_acquire(&rs->iomap_lock); ++ ++ for (entry = rs->iomap_list.next; entry != &rs->iomap_list; ++ entry = entry->next) { ++ iomr = container_of(entry, struct rs_iomap_mr, entry); ++ if (iomr->mr->addr == buf && iomr->mr->length == len) { ++ rs_release_iomap_mr(iomr); ++ goto out; ++ } ++ } ++ ++ for (entry = rs->iomap_queue.next; entry != &rs->iomap_queue; ++ entry = entry->next) { ++ iomr = container_of(entry, struct rs_iomap_mr, entry); ++ if (iomr->mr->addr == buf && iomr->mr->length == len) { ++ rs_release_iomap_mr(iomr); ++ goto out; ++ } ++ } ++ ret = ERR(EINVAL); ++out: ++ fastlock_release(&rs->iomap_lock); ++ return ret; ++} ++ ++size_t riowrite(int socket, const void *buf, size_t count, off_t offset, int flags) ++{ ++ ++} -- 2.46.0