mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-29 01:59:02 +00:00
7d7aa2fd92
This change makes the names of Broadcom targets consistent by using the common notation based on SoC/CPU ID (which is used internally anyway), bcmXXXX instead of brcmXXXX. This is even used for target TITLE in make menuconfig already, only the short target name used brcm so far. Despite, since subtargets range from bcm2708 to bcm2711, it seems appropriate to use bcm27xx instead of bcm2708 (again, as already done for BOARDNAME). This also renames the packages brcm2708-userland and brcm2708-gpu-fw. Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de> Acked-by: Álvaro Fernández Rojas <noltari@gmail.com>
127 lines
4.1 KiB
Diff
127 lines
4.1 KiB
Diff
From 75fdebcf15e8023b9640d9fc2e3ed227e5563968 Mon Sep 17 00:00:00 2001
|
|
From: detule <ogjoneski@gmail.com>
|
|
Date: Tue, 2 Oct 2018 04:10:08 -0400
|
|
Subject: [PATCH] vchiq_2835_arm: Implement a DMA pool for small bulk
|
|
transfers (#2699)
|
|
|
|
During a bulk transfer we request a DMA allocation to hold the
|
|
scatter-gather list. Most of the time, this allocation is small
|
|
(<< PAGE_SIZE), however it can be requested at a high enough frequency
|
|
to cause fragmentation and/or stress the CMA allocator (think time
|
|
spent in compaction here, or during allocations elsewhere).
|
|
|
|
Implement a pool to serve up small DMA allocations, falling back
|
|
to a coherent allocation if the request is greater than
|
|
VCHIQ_DMA_POOL_SIZE.
|
|
|
|
Signed-off-by: Oliver Gjoneski <ogjoneski@gmail.com>
|
|
---
|
|
.../interface/vchiq_arm/vchiq_2835_arm.c | 40 +++++++++++++++----
|
|
1 file changed, 33 insertions(+), 7 deletions(-)
|
|
|
|
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
|
|
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
|
|
@@ -37,6 +37,7 @@
|
|
#include <linux/interrupt.h>
|
|
#include <linux/pagemap.h>
|
|
#include <linux/dma-mapping.h>
|
|
+#include <linux/dmapool.h>
|
|
#include <linux/io.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/uaccess.h>
|
|
@@ -60,6 +61,8 @@
|
|
#define BELL0 0x00
|
|
#define BELL2 0x08
|
|
|
|
+#define VCHIQ_DMA_POOL_SIZE PAGE_SIZE
|
|
+
|
|
struct vchiq_2835_state {
|
|
int inited;
|
|
VCHIQ_ARM_STATE_T arm_state;
|
|
@@ -69,6 +72,7 @@ struct vchiq_pagelist_info {
|
|
PAGELIST_T *pagelist;
|
|
size_t pagelist_buffer_size;
|
|
dma_addr_t dma_addr;
|
|
+ bool is_from_pool;
|
|
enum dma_data_direction dma_dir;
|
|
unsigned int num_pages;
|
|
unsigned int pages_need_release;
|
|
@@ -91,6 +95,7 @@ static void __iomem *g_regs;
|
|
* relevant Device Tree node.
|
|
*/
|
|
static unsigned int g_cache_line_size;
|
|
+static struct dma_pool *g_dma_pool;
|
|
static unsigned int g_fragments_size;
|
|
static char *g_fragments_base;
|
|
static char *g_free_fragments;
|
|
@@ -206,6 +211,14 @@ int vchiq_platform_init(struct platform_
|
|
}
|
|
|
|
g_dev = dev;
|
|
+ g_dma_pool = dmam_pool_create("vchiq_scatter_pool", dev,
|
|
+ VCHIQ_DMA_POOL_SIZE, g_cache_line_size,
|
|
+ 0);
|
|
+ if (!g_dma_pool) {
|
|
+ dev_err(dev, "failed to create dma pool");
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+
|
|
vchiq_log_info(vchiq_arm_log_level,
|
|
"vchiq_init - done (slots %pK, phys %pad)",
|
|
vchiq_slot_zero, &slot_phys);
|
|
@@ -397,9 +410,14 @@ cleanup_pagelistinfo(struct vchiq_pageli
|
|
for (i = 0; i < pagelistinfo->num_pages; i++)
|
|
put_page(pagelistinfo->pages[i]);
|
|
}
|
|
-
|
|
- dma_free_coherent(g_dev, pagelistinfo->pagelist_buffer_size,
|
|
- pagelistinfo->pagelist, pagelistinfo->dma_addr);
|
|
+ if (pagelistinfo->is_from_pool) {
|
|
+ dma_pool_free(g_dma_pool, pagelistinfo->pagelist,
|
|
+ pagelistinfo->dma_addr);
|
|
+ } else {
|
|
+ dma_free_coherent(g_dev, pagelistinfo->pagelist_buffer_size,
|
|
+ pagelistinfo->pagelist,
|
|
+ pagelistinfo->dma_addr);
|
|
+ }
|
|
}
|
|
|
|
/* There is a potential problem with partial cache lines (pages?)
|
|
@@ -419,6 +437,7 @@ create_pagelist(char __user *buf, size_t
|
|
u32 *addrs;
|
|
unsigned int num_pages, offset, i, k;
|
|
int actual_pages;
|
|
+ bool is_from_pool;
|
|
size_t pagelist_size;
|
|
struct scatterlist *scatterlist, *sg;
|
|
int dma_buffers;
|
|
@@ -445,10 +464,16 @@ create_pagelist(char __user *buf, size_t
|
|
/* Allocate enough storage to hold the page pointers and the page
|
|
* list
|
|
*/
|
|
- pagelist = dma_zalloc_coherent(g_dev,
|
|
- pagelist_size,
|
|
- &dma_addr,
|
|
- GFP_KERNEL);
|
|
+ if (pagelist_size > VCHIQ_DMA_POOL_SIZE) {
|
|
+ pagelist = dma_zalloc_coherent(g_dev,
|
|
+ pagelist_size,
|
|
+ &dma_addr,
|
|
+ GFP_KERNEL);
|
|
+ is_from_pool = false;
|
|
+ } else {
|
|
+ pagelist = dma_pool_zalloc(g_dma_pool, GFP_KERNEL, &dma_addr);
|
|
+ is_from_pool = true;
|
|
+ }
|
|
|
|
vchiq_log_trace(vchiq_arm_log_level, "%s - %pK", __func__, pagelist);
|
|
|
|
@@ -469,6 +494,7 @@ create_pagelist(char __user *buf, size_t
|
|
pagelistinfo->pagelist = pagelist;
|
|
pagelistinfo->pagelist_buffer_size = pagelist_size;
|
|
pagelistinfo->dma_addr = dma_addr;
|
|
+ pagelistinfo->is_from_pool = is_from_pool;
|
|
pagelistinfo->dma_dir = (type == PAGELIST_WRITE) ?
|
|
DMA_TO_DEVICE : DMA_FROM_DEVICE;
|
|
pagelistinfo->num_pages = num_pages;
|