Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/sdmmc Defer DIOCCACHESYNC to the sdmmc task queue so...
details: https://anonhg.NetBSD.org/src/rev/2953b7a476d0
branches: trunk
changeset: 445696:2953b7a476d0
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Fri Nov 09 14:39:19 2018 +0000
description:
Defer DIOCCACHESYNC to the sdmmc task queue so they are serialized with other requests.
diffstat:
sys/dev/sdmmc/ld_sdmmc.c | 62 ++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 57 insertions(+), 5 deletions(-)
diffs (119 lines):
diff -r db0736464653 -r 2953b7a476d0 sys/dev/sdmmc/ld_sdmmc.c
--- a/sys/dev/sdmmc/ld_sdmmc.c Fri Nov 09 14:38:36 2018 +0000
+++ b/sys/dev/sdmmc/ld_sdmmc.c Fri Nov 09 14:39:19 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ld_sdmmc.c,v 1.34 2017/08/20 15:58:43 mlelstv Exp $ */
+/* $NetBSD: ld_sdmmc.c,v 1.35 2018/11/09 14:39:19 jmcneill Exp $ */
/*
* Copyright (c) 2008 KIYOHARA Takashi
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.34 2017/08/20 15:58:43 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ld_sdmmc.c,v 1.35 2018/11/09 14:39:19 jmcneill Exp $");
#ifdef _KERNEL_OPT
#include "opt_sdmmc.h"
@@ -78,6 +78,11 @@
struct buf *task_bp;
int task_retries; /* number of xfer retry */
struct callout task_restart_ch;
+
+ kmutex_t task_lock;
+ kcondvar_t task_cv;
+
+ uintptr_t task_data;
};
struct ld_sdmmc_softc {
@@ -91,6 +96,7 @@
struct evcnt sc_ev_discard; /* discard counter */
struct evcnt sc_ev_discarderr; /* discard error counter */
struct evcnt sc_ev_discardbusy; /* discard busy counter */
+ struct evcnt sc_ev_cachesyncbusy; /* cache sync busy counter */
};
static int ld_sdmmc_match(device_t, cfdata_t, void *);
@@ -153,6 +159,8 @@
task = &sc->sc_task[i];
task->task_sc = sc;
callout_init(&task->task_restart_ch, CALLOUT_MPSAFE);
+ mutex_init(&task->task_lock, MUTEX_DEFAULT, IPL_NONE);
+ cv_init(&task->task_cv, "ldsdmmctask");
pcq_put(sc->sc_freeq, task);
}
@@ -224,8 +232,11 @@
return rv;
ldenddetach(ld);
- for (i = 0; i < __arraycount(sc->sc_task); i++)
+ for (i = 0; i < __arraycount(sc->sc_task); i++) {
callout_destroy(&sc->sc_task[i].task_restart_ch);
+ mutex_destroy(&sc->sc_task[i].task_lock);
+ cv_destroy(&sc->sc_task[i].task_cv);
+ }
pcq_destroy(sc->sc_freeq);
evcnt_detach(&sc->sc_ev_discard);
@@ -379,15 +390,56 @@
return 0;
}
+static void
+ld_sdmmc_docachesync(void *arg)
+{
+ struct ld_sdmmc_task *task = arg;
+ struct ld_sdmmc_softc *sc = task->task_sc;
+ const bool poll = (bool)task->task_data;
+
+ task->task_data = sdmmc_mem_flush_cache(sc->sc_sf, poll);
+
+ mutex_enter(&task->task_lock);
+ cv_signal(&task->task_cv);
+ mutex_exit(&task->task_lock);
+}
+
+static int
+ld_sdmmc_cachesync(struct ld_softc *ld, bool poll)
+{
+ struct ld_sdmmc_softc *sc = device_private(ld->sc_dv);
+ struct ld_sdmmc_task *task = pcq_get(sc->sc_freeq);
+ int error = 0;
+
+ if (task == NULL) {
+ sc->sc_ev_cachesyncbusy.ev_count++;
+ return EBUSY;
+ }
+
+ sdmmc_init_task(&task->task, ld_sdmmc_docachesync, task);
+ task->task_data = poll;
+
+ mutex_enter(&task->task_lock);
+ sdmmc_add_task(sc->sc_sf->sc, &task->task);
+ error = cv_wait_sig(&task->task_cv, &task->task_lock);
+ mutex_exit(&task->task_lock);
+
+ if (error == 0)
+ error = (int)task->task_data;
+
+ pcq_put(sc->sc_freeq, task);
+
+ return error;
+}
+
static int
ld_sdmmc_ioctl(struct ld_softc *ld, u_long cmd, void *addr, int32_t flag,
bool poll)
{
- struct ld_sdmmc_softc *sc = device_private(ld->sc_dv);
switch (cmd) {
case DIOCCACHESYNC:
- return sdmmc_mem_flush_cache(sc->sc_sf, poll);
+ return ld_sdmmc_cachesync(ld, poll);
default:
return EPASSTHROUGH;
}
Home |
Main Index |
Thread Index |
Old Index