aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/rdma/vmw/pvrdma.h5
-rw-r--r--hw/rdma/vmw/pvrdma_cmd.c6
-rw-r--r--hw/rdma/vmw/pvrdma_dev_ring.c41
-rw-r--r--hw/rdma/vmw/pvrdma_dev_ring.h9
-rw-r--r--hw/rdma/vmw/pvrdma_main.c4
5 files changed, 37 insertions, 28 deletions
diff --git a/hw/rdma/vmw/pvrdma.h b/hw/rdma/vmw/pvrdma.h
index 1d36a76..d08965d 100644
--- a/hw/rdma/vmw/pvrdma.h
+++ b/hw/rdma/vmw/pvrdma.h
@@ -26,7 +26,6 @@
#include "../rdma_backend_defs.h"
#include "../rdma_rm_defs.h"
-#include "standard-headers/drivers/infiniband/hw/vmw_pvrdma/pvrdma_ring.h"
#include "standard-headers/drivers/infiniband/hw/vmw_pvrdma/pvrdma_dev_api.h"
#include "pvrdma_dev_ring.h"
#include "qom/object.h"
@@ -64,10 +63,10 @@ typedef struct DSRInfo {
union pvrdma_cmd_req *req;
union pvrdma_cmd_resp *rsp;
- struct pvrdma_ring *async_ring_state;
+ PvrdmaRingState *async_ring_state;
PvrdmaRing async;
- struct pvrdma_ring *cq_ring_state;
+ PvrdmaRingState *cq_ring_state;
PvrdmaRing cq;
} DSRInfo;
diff --git a/hw/rdma/vmw/pvrdma_cmd.c b/hw/rdma/vmw/pvrdma_cmd.c
index 692125a..f59879e 100644
--- a/hw/rdma/vmw/pvrdma_cmd.c
+++ b/hw/rdma/vmw/pvrdma_cmd.c
@@ -262,7 +262,7 @@ static int create_cq_ring(PCIDevice *pci_dev , PvrdmaRing **ring,
r = g_malloc(sizeof(*r));
*ring = r;
- r->ring_state = (struct pvrdma_ring *)
+ r->ring_state = (PvrdmaRingState *)
rdma_pci_dma_map(pci_dev, tbl[0], TARGET_PAGE_SIZE);
if (!r->ring_state) {
@@ -398,7 +398,7 @@ static int create_qp_rings(PCIDevice *pci_dev, uint64_t pdir_dma,
*rings = sr;
/* Create send ring */
- sr->ring_state = (struct pvrdma_ring *)
+ sr->ring_state = (PvrdmaRingState *)
rdma_pci_dma_map(pci_dev, tbl[0], TARGET_PAGE_SIZE);
if (!sr->ring_state) {
rdma_error_report("Failed to map to QP ring state");
@@ -639,7 +639,7 @@ static int create_srq_ring(PCIDevice *pci_dev, PvrdmaRing **ring,
r = g_malloc(sizeof(*r));
*ring = r;
- r->ring_state = (struct pvrdma_ring *)
+ r->ring_state = (PvrdmaRingState *)
rdma_pci_dma_map(pci_dev, tbl[0], TARGET_PAGE_SIZE);
if (!r->ring_state) {
rdma_error_report("Failed to map tp SRQ ring state");
diff --git a/hw/rdma/vmw/pvrdma_dev_ring.c b/hw/rdma/vmw/pvrdma_dev_ring.c
index f0bcde7..074ac59 100644
--- a/hw/rdma/vmw/pvrdma_dev_ring.c
+++ b/hw/rdma/vmw/pvrdma_dev_ring.c
@@ -22,11 +22,10 @@
#include "trace.h"
#include "../rdma_utils.h"
-#include "standard-headers/drivers/infiniband/hw/vmw_pvrdma/pvrdma_ring.h"
#include "pvrdma_dev_ring.h"
int pvrdma_ring_init(PvrdmaRing *ring, const char *name, PCIDevice *dev,
- struct pvrdma_ring *ring_state, uint32_t max_elems,
+ PvrdmaRingState *ring_state, uint32_t max_elems,
size_t elem_sz, dma_addr_t *tbl, uint32_t npages)
{
int i;
@@ -73,48 +72,54 @@ out:
void *pvrdma_ring_next_elem_read(PvrdmaRing *ring)
{
- int e;
- unsigned int idx = 0, offset;
+ unsigned int idx, offset;
+ const uint32_t tail = qatomic_read(&ring->ring_state->prod_tail);
+ const uint32_t head = qatomic_read(&ring->ring_state->cons_head);
- e = pvrdma_idx_ring_has_data(ring->ring_state, ring->max_elems, &idx);
- if (e <= 0) {
+ if (tail & ~((ring->max_elems << 1) - 1) ||
+ head & ~((ring->max_elems << 1) - 1) ||
+ tail == head) {
trace_pvrdma_ring_next_elem_read_no_data(ring->name);
return NULL;
}
+ idx = head & (ring->max_elems - 1);
offset = idx * ring->elem_sz;
return ring->pages[offset / TARGET_PAGE_SIZE] + (offset % TARGET_PAGE_SIZE);
}
void pvrdma_ring_read_inc(PvrdmaRing *ring)
{
- pvrdma_idx_ring_inc(&ring->ring_state->cons_head, ring->max_elems);
+ uint32_t idx = qatomic_read(&ring->ring_state->cons_head);
+
+ idx = (idx + 1) & ((ring->max_elems << 1) - 1);
+ qatomic_set(&ring->ring_state->cons_head, idx);
}
void *pvrdma_ring_next_elem_write(PvrdmaRing *ring)
{
- int idx;
- unsigned int offset, tail;
+ unsigned int idx, offset;
+ const uint32_t tail = qatomic_read(&ring->ring_state->prod_tail);
+ const uint32_t head = qatomic_read(&ring->ring_state->cons_head);
- idx = pvrdma_idx_ring_has_space(ring->ring_state, ring->max_elems, &tail);
- if (idx <= 0) {
+ if (tail & ~((ring->max_elems << 1) - 1) ||
+ head & ~((ring->max_elems << 1) - 1) ||
+ tail == (head ^ ring->max_elems)) {
rdma_error_report("CQ is full");
return NULL;
}
- idx = pvrdma_idx(&ring->ring_state->prod_tail, ring->max_elems);
- if (idx < 0 || tail != idx) {
- rdma_error_report("Invalid idx %d", idx);
- return NULL;
- }
-
+ idx = tail & (ring->max_elems - 1);
offset = idx * ring->elem_sz;
return ring->pages[offset / TARGET_PAGE_SIZE] + (offset % TARGET_PAGE_SIZE);
}
void pvrdma_ring_write_inc(PvrdmaRing *ring)
{
- pvrdma_idx_ring_inc(&ring->ring_state->prod_tail, ring->max_elems);
+ uint32_t idx = qatomic_read(&ring->ring_state->prod_tail);
+
+ idx = (idx + 1) & ((ring->max_elems << 1) - 1);
+ qatomic_set(&ring->ring_state->prod_tail, idx);
}
void pvrdma_ring_free(PvrdmaRing *ring)
diff --git a/hw/rdma/vmw/pvrdma_dev_ring.h b/hw/rdma/vmw/pvrdma_dev_ring.h
index 5f2a0cf..d231588 100644
--- a/hw/rdma/vmw/pvrdma_dev_ring.h
+++ b/hw/rdma/vmw/pvrdma_dev_ring.h
@@ -19,18 +19,23 @@
#define MAX_RING_NAME_SZ 32
+typedef struct PvrdmaRingState {
+ int prod_tail; /* producer tail */
+ int cons_head; /* consumer head */
+} PvrdmaRingState;
+
typedef struct PvrdmaRing {
char name[MAX_RING_NAME_SZ];
PCIDevice *dev;
uint32_t max_elems;
size_t elem_sz;
- struct pvrdma_ring *ring_state; /* used only for unmap */
+ PvrdmaRingState *ring_state; /* used only for unmap */
int npages;
void **pages;
} PvrdmaRing;
int pvrdma_ring_init(PvrdmaRing *ring, const char *name, PCIDevice *dev,
- struct pvrdma_ring *ring_state, uint32_t max_elems,
+ PvrdmaRingState *ring_state, uint32_t max_elems,
size_t elem_sz, dma_addr_t *tbl, uint32_t npages);
void *pvrdma_ring_next_elem_read(PvrdmaRing *ring);
void pvrdma_ring_read_inc(PvrdmaRing *ring);
diff --git a/hw/rdma/vmw/pvrdma_main.c b/hw/rdma/vmw/pvrdma_main.c
index 8593570..84ae802 100644
--- a/hw/rdma/vmw/pvrdma_main.c
+++ b/hw/rdma/vmw/pvrdma_main.c
@@ -85,7 +85,7 @@ static void free_dev_ring(PCIDevice *pci_dev, PvrdmaRing *ring,
rdma_pci_dma_unmap(pci_dev, ring_state, TARGET_PAGE_SIZE);
}
-static int init_dev_ring(PvrdmaRing *ring, struct pvrdma_ring **ring_state,
+static int init_dev_ring(PvrdmaRing *ring, PvrdmaRingState **ring_state,
const char *name, PCIDevice *pci_dev,
dma_addr_t dir_addr, uint32_t num_pages)
{
@@ -114,7 +114,7 @@ static int init_dev_ring(PvrdmaRing *ring, struct pvrdma_ring **ring_state,
/* RX ring is the second */
(*ring_state)++;
rc = pvrdma_ring_init(ring, name, pci_dev,
- (struct pvrdma_ring *)*ring_state,
+ (PvrdmaRingState *)*ring_state,
(num_pages - 1) * TARGET_PAGE_SIZE /
sizeof(struct pvrdma_cqne),
sizeof(struct pvrdma_cqne),