mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-13 10:02:38 +00:00
Fix completion descriptors alignment for the ENA
The latest generation hardware requires IO CQ (completion queue) descriptors memory to be aligned to a 4K. It needs that feature for the best performance. Allocating unaligned descriptors will have a big performance impact as the packet processing in a HW won't be optimized properly. For that purpose adjust ena_dma_alloc() to support it. It's a critical fix, especially for the arm64 EC2 instances. Submitted by: Ido Segev <idose@amazon.com> Obtained from: Amazon, Inc MFC after: 1 week Differential revision: https://reviews.freebsd.org/D27114
This commit is contained in:
commit
4f8f476e73
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=367795
@ -449,19 +449,21 @@ static int ena_com_init_io_cq(struct ena_com_dev *ena_dev,
|
||||
size = io_cq->cdesc_entry_size_in_bytes * io_cq->q_depth;
|
||||
io_cq->bus = ena_dev->bus;
|
||||
|
||||
ENA_MEM_ALLOC_COHERENT_NODE(ena_dev->dmadev,
|
||||
size,
|
||||
io_cq->cdesc_addr.virt_addr,
|
||||
io_cq->cdesc_addr.phys_addr,
|
||||
io_cq->cdesc_addr.mem_handle,
|
||||
ctx->numa_node,
|
||||
prev_node);
|
||||
ENA_MEM_ALLOC_COHERENT_NODE_ALIGNED(ena_dev->dmadev,
|
||||
size,
|
||||
io_cq->cdesc_addr.virt_addr,
|
||||
io_cq->cdesc_addr.phys_addr,
|
||||
io_cq->cdesc_addr.mem_handle,
|
||||
ctx->numa_node,
|
||||
prev_node,
|
||||
ENA_CDESC_RING_SIZE_ALIGNMENT);
|
||||
if (!io_cq->cdesc_addr.virt_addr) {
|
||||
ENA_MEM_ALLOC_COHERENT(ena_dev->dmadev,
|
||||
size,
|
||||
io_cq->cdesc_addr.virt_addr,
|
||||
io_cq->cdesc_addr.phys_addr,
|
||||
io_cq->cdesc_addr.mem_handle);
|
||||
ENA_MEM_ALLOC_COHERENT_ALIGNED(ena_dev->dmadev,
|
||||
size,
|
||||
io_cq->cdesc_addr.virt_addr,
|
||||
io_cq->cdesc_addr.phys_addr,
|
||||
io_cq->cdesc_addr.mem_handle,
|
||||
ENA_CDESC_RING_SIZE_ALIGNMENT);
|
||||
}
|
||||
|
||||
if (!io_cq->cdesc_addr.virt_addr) {
|
||||
|
@ -51,6 +51,8 @@
|
||||
#define ADMIN_CQ_SIZE(depth) ((depth) * sizeof(struct ena_admin_acq_entry))
|
||||
#define ADMIN_AENQ_SIZE(depth) ((depth) * sizeof(struct ena_admin_aenq_entry))
|
||||
|
||||
#define ENA_CDESC_RING_SIZE_ALIGNMENT (1 << 12) /* 4K */
|
||||
|
||||
/*****************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/* ENA adaptive interrupt moderation settings */
|
||||
|
@ -106,6 +106,8 @@ extern struct ena_bus_space ebs;
|
||||
#define ENA_ADMQ (1 << 8) /* Detailed info about admin queue. */
|
||||
#define ENA_NETMAP (1 << 9) /* Detailed info about netmap. */
|
||||
|
||||
#define DEFAULT_ALLOC_ALIGNMENT 8
|
||||
|
||||
extern int ena_log_level;
|
||||
|
||||
#define ena_trace_raw(level, fmt, args...) \
|
||||
@ -285,7 +287,7 @@ typedef uint64_t ena_time_t;
|
||||
void ena_dmamap_callback(void *arg, bus_dma_segment_t *segs, int nseg,
|
||||
int error);
|
||||
int ena_dma_alloc(device_t dmadev, bus_size_t size, ena_mem_handle_t *dma,
|
||||
int mapflags);
|
||||
int mapflags, bus_size_t alignment);
|
||||
|
||||
static inline uint32_t
|
||||
ena_reg_read32(struct ena_bus *bus, bus_size_t offset)
|
||||
@ -313,20 +315,30 @@ ena_reg_read32(struct ena_bus *bus, bus_size_t offset)
|
||||
(void)(size); \
|
||||
free(ptr, M_DEVBUF); \
|
||||
} while (0)
|
||||
#define ENA_MEM_ALLOC_COHERENT_NODE(dmadev, size, virt, phys, handle, node, \
|
||||
dev_node) \
|
||||
#define ENA_MEM_ALLOC_COHERENT_NODE_ALIGNED(dmadev, size, virt, phys, \
|
||||
handle, node, dev_node, alignment) \
|
||||
do { \
|
||||
((virt) = NULL); \
|
||||
(void)(dev_node); \
|
||||
} while (0)
|
||||
|
||||
#define ENA_MEM_ALLOC_COHERENT(dmadev, size, virt, phys, dma) \
|
||||
#define ENA_MEM_ALLOC_COHERENT_NODE(dmadev, size, virt, phys, handle, \
|
||||
node, dev_node) \
|
||||
ENA_MEM_ALLOC_COHERENT_NODE_ALIGNED(dmadev, size, virt, \
|
||||
phys, handle, node, dev_node, DEFAULT_ALLOC_ALIGNMENT)
|
||||
|
||||
#define ENA_MEM_ALLOC_COHERENT_ALIGNED(dmadev, size, virt, phys, dma, \
|
||||
alignment) \
|
||||
do { \
|
||||
ena_dma_alloc((dmadev), (size), &(dma), 0); \
|
||||
ena_dma_alloc((dmadev), (size), &(dma), 0, alignment); \
|
||||
(virt) = (void *)(dma).vaddr; \
|
||||
(phys) = (dma).paddr; \
|
||||
} while (0)
|
||||
|
||||
#define ENA_MEM_ALLOC_COHERENT(dmadev, size, virt, phys, dma) \
|
||||
ENA_MEM_ALLOC_COHERENT_ALIGNED(dmadev, size, virt, \
|
||||
phys, dma, DEFAULT_ALLOC_ALIGNMENT)
|
||||
|
||||
#define ENA_MEM_FREE_COHERENT(dmadev, size, virt, phys, dma) \
|
||||
do { \
|
||||
(void)size; \
|
||||
|
@ -200,7 +200,7 @@ ena_dmamap_callback(void *arg, bus_dma_segment_t *segs, int nseg, int error)
|
||||
|
||||
int
|
||||
ena_dma_alloc(device_t dmadev, bus_size_t size,
|
||||
ena_mem_handle_t *dma , int mapflags)
|
||||
ena_mem_handle_t *dma, int mapflags, bus_size_t alignment)
|
||||
{
|
||||
struct ena_adapter* adapter = device_get_softc(dmadev);
|
||||
uint32_t maxsize;
|
||||
@ -214,7 +214,7 @@ ena_dma_alloc(device_t dmadev, bus_size_t size,
|
||||
dma_space_addr = BUS_SPACE_MAXADDR;
|
||||
|
||||
error = bus_dma_tag_create(bus_get_dma_tag(dmadev), /* parent */
|
||||
8, 0, /* alignment, bounds */
|
||||
alignment, 0, /* alignment, bounds */
|
||||
dma_space_addr, /* lowaddr of exclusion window */
|
||||
BUS_SPACE_MAXADDR,/* highaddr of exclusion window */
|
||||
NULL, NULL, /* filter, filterarg */
|
||||
|
Loading…
Reference in New Issue
Block a user