]> git.proxmox.com Git - mirror_qemu.git/blame - hw/rdma/vmw/pvrdma_dev_ring.c
Drop duplicate #include
[mirror_qemu.git] / hw / rdma / vmw / pvrdma_dev_ring.c
CommitLineData
98d176f8
YS
1/*
2 * QEMU paravirtual RDMA - Device rings
3 *
4 * Copyright (C) 2018 Oracle
5 * Copyright (C) 2018 Red Hat Inc
6 *
7 * Authors:
8 * Yuval Shaia <yuval.shaia@oracle.com>
9 * Marcel Apfelbaum <marcel@redhat.com>
10 *
11 * This work is licensed under the terms of the GNU GPL, version 2 or later.
12 * See the COPYING file in the top-level directory.
13 *
14 */
15
0efc9511
MT
16#include "qemu/osdep.h"
17#include "hw/pci/pci.h"
18#include "cpu.h"
1d2695ef 19#include "qemu/cutils.h"
98d176f8 20
4d71b38a
YS
21#include "trace.h"
22
98d176f8 23#include "../rdma_utils.h"
98d176f8
YS
24#include "pvrdma_dev_ring.h"
25
26int pvrdma_ring_init(PvrdmaRing *ring, const char *name, PCIDevice *dev,
3aa1b7af 27 PvrdmaRingState *ring_state, uint32_t max_elems,
6f559013 28 size_t elem_sz, dma_addr_t *tbl, uint32_t npages)
98d176f8
YS
29{
30 int i;
31 int rc = 0;
32
1d2695ef 33 pstrcpy(ring->name, MAX_RING_NAME_SZ, name);
98d176f8
YS
34 ring->dev = dev;
35 ring->ring_state = ring_state;
36 ring->max_elems = max_elems;
37 ring->elem_sz = elem_sz;
98d176f8 38 /* TODO: Give a moment to think if we want to redo driver settings
d73415a3
SH
39 qatomic_set(&ring->ring_state->prod_tail, 0);
40 qatomic_set(&ring->ring_state->cons_head, 0);
98d176f8
YS
41 */
42 ring->npages = npages;
b21e2380 43 ring->pages = g_new0(void *, npages);
98d176f8
YS
44
45 for (i = 0; i < npages; i++) {
46 if (!tbl[i]) {
4d71b38a 47 rdma_error_report("npages=%d but tbl[%d] is NULL", npages, i);
98d176f8
YS
48 continue;
49 }
50
51 ring->pages[i] = rdma_pci_dma_map(dev, tbl[i], TARGET_PAGE_SIZE);
52 if (!ring->pages[i]) {
53 rc = -ENOMEM;
4d71b38a 54 rdma_error_report("Failed to map to page %d in ring %s", i, name);
98d176f8
YS
55 goto out_free;
56 }
57 memset(ring->pages[i], 0, TARGET_PAGE_SIZE);
58 }
59
60 goto out;
61
62out_free:
63 while (i--) {
64 rdma_pci_dma_unmap(dev, ring->pages[i], TARGET_PAGE_SIZE);
65 }
66 g_free(ring->pages);
67
68out:
69 return rc;
70}
71
72void *pvrdma_ring_next_elem_read(PvrdmaRing *ring)
73{
3aa1b7af
CH
74 unsigned int idx, offset;
75 const uint32_t tail = qatomic_read(&ring->ring_state->prod_tail);
76 const uint32_t head = qatomic_read(&ring->ring_state->cons_head);
98d176f8 77
3aa1b7af
CH
78 if (tail & ~((ring->max_elems << 1) - 1) ||
79 head & ~((ring->max_elems << 1) - 1) ||
80 tail == head) {
4d71b38a 81 trace_pvrdma_ring_next_elem_read_no_data(ring->name);
98d176f8
YS
82 return NULL;
83 }
84
3aa1b7af 85 idx = head & (ring->max_elems - 1);
98d176f8 86 offset = idx * ring->elem_sz;
98d176f8
YS
87 return ring->pages[offset / TARGET_PAGE_SIZE] + (offset % TARGET_PAGE_SIZE);
88}
89
90void pvrdma_ring_read_inc(PvrdmaRing *ring)
91{
3aa1b7af
CH
92 uint32_t idx = qatomic_read(&ring->ring_state->cons_head);
93
94 idx = (idx + 1) & ((ring->max_elems << 1) - 1);
95 qatomic_set(&ring->ring_state->cons_head, idx);
98d176f8
YS
96}
97
98void *pvrdma_ring_next_elem_write(PvrdmaRing *ring)
99{
3aa1b7af
CH
100 unsigned int idx, offset;
101 const uint32_t tail = qatomic_read(&ring->ring_state->prod_tail);
102 const uint32_t head = qatomic_read(&ring->ring_state->cons_head);
98d176f8 103
3aa1b7af
CH
104 if (tail & ~((ring->max_elems << 1) - 1) ||
105 head & ~((ring->max_elems << 1) - 1) ||
106 tail == (head ^ ring->max_elems)) {
4d71b38a 107 rdma_error_report("CQ is full");
98d176f8
YS
108 return NULL;
109 }
110
3aa1b7af 111 idx = tail & (ring->max_elems - 1);
98d176f8
YS
112 offset = idx * ring->elem_sz;
113 return ring->pages[offset / TARGET_PAGE_SIZE] + (offset % TARGET_PAGE_SIZE);
114}
115
116void pvrdma_ring_write_inc(PvrdmaRing *ring)
117{
3aa1b7af
CH
118 uint32_t idx = qatomic_read(&ring->ring_state->prod_tail);
119
120 idx = (idx + 1) & ((ring->max_elems << 1) - 1);
121 qatomic_set(&ring->ring_state->prod_tail, idx);
98d176f8
YS
122}
123
124void pvrdma_ring_free(PvrdmaRing *ring)
125{
126 if (!ring) {
127 return;
128 }
129
130 if (!ring->pages) {
131 return;
132 }
133
98d176f8
YS
134 while (ring->npages--) {
135 rdma_pci_dma_unmap(ring->dev, ring->pages[ring->npages],
136 TARGET_PAGE_SIZE);
137 }
138
139 g_free(ring->pages);
140 ring->pages = NULL;
141}