Simplify swi for bus_dma.

When a DMA request using bounce pages completes, a swi is triggered to
schedule pending DMA requests using the just-freed bounce pages.  For
a long time this bus_dma swi has been tied to a "virtual memory" swi
(swi_vm).  However, all of the swi_vm implementations are the same and
consist of checking a flag (busdma_swi_pending) which is always true
and if set calling busdma_swi.  I suspect this dates back to the
pre-SMPng days and that the intention was for swi_vm to serve as a
mux.  However, in the current scheme there's no need for the mux.

Instead, remove swi_vm and vm_ih.  Each bus_dma implementation that
uses bounce pages is responsible for creating its own swi (busdma_ih)
which it now schedules directly.  This swi invokes busdma_swi directly
removing the need for busdma_swi_pending.

One consequence is that the swi now works on RISC-V which had previously
failed to invoke busdma_swi from swi_vm.

Reviewed by:	imp, kib
Sponsored by:	Netflix
Differential Revision:	https://reviews.freebsd.org/D33447
This commit is contained in:
John Baldwin
2021-12-28 13:51:25 -08:00
parent 2262f7dcf4
commit 254e4e5b77
28 changed files with 109 additions and 127 deletions
+18 -6
View File
@@ -114,8 +114,6 @@ struct sync_list {
bus_size_t datacount; /* client data count */
};
int busdma_swi_pending;
struct bounce_zone {
STAILQ_ENTRY(bounce_zone) links;
STAILQ_HEAD(bp_list, bounce_page) bounce_page_list;
@@ -151,6 +149,7 @@ static counter_u64_t maploads_physmem;
#endif
static STAILQ_HEAD(, bounce_zone) bounce_zone_list;
static void *busdma_ih;
SYSCTL_NODE(_hw, OID_AUTO, busdma, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
"Busdma parameters");
@@ -1714,6 +1713,7 @@ free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage)
{
struct bus_dmamap *map;
struct bounce_zone *bz;
bool schedule_swi;
bz = dmat->bounce_zone;
bpage->datavaddr = 0;
@@ -1728,6 +1728,7 @@ free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage)
bpage->busaddr &= ~PAGE_MASK;
}
schedule_swi = false;
mtx_lock(&bounce_lock);
STAILQ_INSERT_HEAD(&bz->bounce_page_list, bpage, links);
bz->free_bpages++;
@@ -1737,16 +1738,17 @@ free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage)
STAILQ_REMOVE_HEAD(&bounce_map_waitinglist, links);
STAILQ_INSERT_TAIL(&bounce_map_callbacklist,
map, links);
busdma_swi_pending = 1;
bz->total_deferred++;
swi_sched(vm_ih, 0);
schedule_swi = true;
}
}
mtx_unlock(&bounce_lock);
if (schedule_swi)
swi_sched(busdma_ih, 0);
}
void
busdma_swi(void)
static void
busdma_swi(void *dummy __unused)
{
bus_dma_tag_t dmat;
struct bus_dmamap *map;
@@ -1764,3 +1766,13 @@ busdma_swi(void)
}
mtx_unlock(&bounce_lock);
}
static void
start_busdma_swi(void *dummy __unused)
{
if (swi_add(NULL, "busdma", busdma_swi, NULL, SWI_BUSDMA, INTR_MPSAFE,
&busdma_ih))
panic("died while creating busdma swi ithread");
}
SYSINIT(start_busdma_swi, SI_SUB_SOFTINTR, SI_ORDER_ANY, start_busdma_swi,
NULL);
-11
View File
@@ -290,17 +290,6 @@ cpu_fork_kthread_handler(struct thread *td, void (*func)(void *), void *arg)
td->td_pcb->pcb_regs.sf_r5 = (register_t)arg; /* first arg */
}
/*
* Software interrupt handler for queued VM system processing.
*/
void
swi_vm(void *dummy)
{
if (busdma_swi_pending)
busdma_swi();
}
void
cpu_exit(struct thread *td)
{
-1
View File
@@ -8,7 +8,6 @@
#include <machine/frame.h>
void cpu_halt(void);
void swi_vm(void *);
#ifdef _KERNEL
#include <machine/cpu-v6.h>
-2
View File
@@ -53,8 +53,6 @@ extern enum cpu_class cpu_class;
struct dumperinfo;
struct minidumpstate;
extern int busdma_swi_pending;
void busdma_swi(void);
int cpu_minidumpsys(struct dumperinfo *, const struct minidumpstate *);
extern uint32_t initial_fpscr;