Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/jdolecek-ncq]: src/sys/dev make ata_xfer's allocated as part of ata_queu...
details: https://anonhg.NetBSD.org/src/rev/3841969bc5c3
branches: jdolecek-ncq
changeset: 352624:3841969bc5c3
user: jdolecek <jdolecek%NetBSD.org@localhost>
date: Sat Apr 15 12:01:23 2017 +0000
description:
make ata_xfer's allocated as part of ata_queue and make it include ata_bio;
they are pre-allocated on attach and ata_get_xfer() now never sleep, drop the
pool
modify wd(4) to file the bio requests using the xfers and hence
make it possible to have more than one active I/O request in flight;
ata_bio callback doesn't need to allocate any memory any more,
require it to never return ATACMD_TRY_AGAIN
move lp, badsect, multi from ata_bio to ata_drive_datas, as they are per-drive,
not per transfer
drop unused drv atac_claim_hw/atac_free_hw hooks, and also drop again ata_bio
c_hwslot
diffstat:
sys/dev/ata/ata.c | 119 +++++++------------
sys/dev/ata/ata_wdc.c | 71 +++++------
sys/dev/ata/atavar.h | 103 +++++++++--------
sys/dev/ata/satafis_subr.c | 9 +-
sys/dev/ata/wd.c | 265 +++++++++++++++++++++++++++-----------------
sys/dev/ata/wdvar.h | 14 +-
sys/dev/ic/ahcisata_core.c | 32 ++---
sys/dev/ic/mvsata.c | 63 ++++-----
sys/dev/ic/siisata.c | 23 +--
sys/dev/ic/wdc.c | 7 +-
sys/dev/scsipi/atapi_wdc.c | 6 +-
sys/dev/usb/umass_isdata.c | 56 +++++----
12 files changed, 387 insertions(+), 381 deletions(-)
diffs (truncated from 2033 to 300 lines):
diff -r 3735afc630e5 -r 3841969bc5c3 sys/dev/ata/ata.c
--- a/sys/dev/ata/ata.c Wed Apr 12 22:28:20 2017 +0000
+++ b/sys/dev/ata/ata.c Sat Apr 15 12:01:23 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ata.c,v 1.132.8.2 2017/04/11 18:15:03 jdolecek Exp $ */
+/* $NetBSD: ata.c,v 1.132.8.3 2017/04/15 12:01:23 jdolecek Exp $ */
/*
* Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved.
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.2 2017/04/11 18:15:03 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.3 2017/04/15 12:01:23 jdolecek Exp $");
#include "opt_ata.h"
@@ -37,7 +37,6 @@
#include <sys/conf.h>
#include <sys/fcntl.h>
#include <sys/proc.h>
-#include <sys/pool.h>
#include <sys/kthread.h>
#include <sys/errno.h>
#include <sys/ataio.h>
@@ -45,6 +44,7 @@
#include <sys/intr.h>
#include <sys/bus.h>
#include <sys/once.h>
+#include <sys/bitops.h>
#define ATABUS_PRIVATE
@@ -84,7 +84,6 @@
#endif
static ONCE_DECL(ata_init_ctrl);
-static struct pool ata_xfer_pool;
/*
* A queue of atabus instances, used to ensure the same bus probe order
@@ -139,8 +138,6 @@
atabus_init(void)
{
- pool_init(&ata_xfer_pool, sizeof(struct ata_xfer), 0, 0, 0,
- "ataspl", NULL, IPL_BIO);
TAILQ_INIT(&atabus_initq_head);
mutex_init(&atabus_qlock, MUTEX_DEFAULT, IPL_NONE);
cv_init(&atabus_qcv, "atainitq");
@@ -187,29 +184,18 @@
{
/* make sure that we can use polled commands */
TAILQ_INIT(&chq->queue_xfer);
+ TAILQ_INIT(&chq->active_xfers);
chq->queue_freeze = 0;
chq->queue_active = 0;
- for (u_int i = 0; i < chq->queue_openings; i++) {
- chq->active_xfers[0] = NULL;
- }
}
struct ata_xfer *
ata_queue_hwslot_to_xfer(struct ata_queue *chq, int hwslot)
{
KASSERT(hwslot < chq->queue_openings);
- if (chq->queue_openings == 1) {
- struct ata_xfer *xfer = chq->active_xfers[0];
- KASSERT(xfer == NULL || xfer->c_hwslot == hwslot);
- return xfer;
- }
- for (u_int i = 0; i < chq->queue_openings; i++) {
- struct ata_xfer *xfer = chq->active_xfers[i];
- if (xfer != NULL && xfer->c_hwslot == hwslot) {
- return xfer;
- }
- }
- return NULL;
+ KASSERT((chq->queue_xfers_avail & __BIT(hwslot)) == 0);
+
+ return &chq->queue_xfers[hwslot];
}
struct ata_queue *
@@ -217,10 +203,11 @@
{
if (openings == 0)
openings = 1;
- struct ata_queue *chq = malloc(offsetof(struct ata_queue, active_xfers[openings]),
+ struct ata_queue *chq = malloc(offsetof(struct ata_queue, queue_xfers[openings]),
M_DEVBUF, M_WAITOK);
if (chq != NULL) {
chq->queue_openings = openings;
+ chq->queue_xfers_avail = (1 << openings) - 1;
ata_queue_reset(chq);
}
return chq;
@@ -520,11 +507,9 @@
*/
chq->queue_freeze--;
u_int active __diagused = 0;
- for (i = 0; i < chq->queue_openings; i++) {
- if ((xfer = chq->active_xfers[i]) != NULL) {
- (*xfer->c_start)(xfer->c_chp, xfer);
- active++;
- }
+ TAILQ_FOREACH(xfer, &chq->active_xfers, c_activechain) {
+ (*xfer->c_start)(xfer->c_chp, xfer);
+ active++;
}
KASSERT(active == chq->queue_active);
} else if (chq->queue_freeze > 1)
@@ -961,7 +946,6 @@
/* complete xfer setup */
xfer->c_chp = chp;
- xfer->c_slot = 0;
/* insert at the end of command list */
TAILQ_INSERT_TAIL(&chp->ch_queue->queue_xfer, xfer, c_xferchain);
@@ -1053,11 +1037,6 @@
if ((chp->ch_flags & ATACH_IRQ_WAIT) != 0)
panic("atastart: channel waiting for irq");
#endif
- if (atac->atac_claim_hw) {
- if (!(*atac->atac_claim_hw)(chp, 0))
- return;
- }
-
ATADEBUG_PRINT(("atastart: xfer %p channel %d drive %d\n", xfer,
chp->ch_channel, xfer->c_drive), DEBUG_XFERS);
if (drvp->drive_flags & ATA_DRIVE_RESET) {
@@ -1065,18 +1044,6 @@
drvp->state = 0;
}
- if (chq->queue_openings == 1) {
- xfer->c_slot = 0;
- xfer->c_hwslot = 0;
- } else {
- for (u_int slot = 0; slot < chq->queue_openings; slot++) {
- if (chq->active_xfers[slot] == NULL) {
- xfer->c_slot = slot;
- xfer->c_hwslot = slot;
- break;
- }
- }
- }
ata_activate_xfer(chp, xfer);
if (atac->atac_cap & ATAC_CAP_NOIRQ)
@@ -1086,26 +1053,34 @@
}
struct ata_xfer *
-ata_get_xfer(int flags)
+ata_get_xfer(struct ata_channel *chp)
{
- struct ata_xfer *xfer;
+ struct ata_queue *chq = chp->ch_queue;
+ struct ata_xfer *xfer = NULL;
int s;
+ uint32_t avail, slot;
s = splbio();
- xfer = pool_get(&ata_xfer_pool,
- ((flags & ATAXF_NOSLEEP) != 0 ? PR_NOWAIT : PR_WAITOK));
+ avail = ffs32(chq->queue_xfers_avail);
+ if (avail == 0)
+ goto out;
+
+ slot = avail - 1;
+ xfer = &chq->queue_xfers[slot];
+ chq->queue_xfers_avail &= ~__BIT(slot);
+
+ memset(xfer, 0, sizeof(struct ata_xfer));
+ xfer->c_slot = slot;
+
+out:
splx(s);
- if (xfer != NULL) {
- memset(xfer, 0, sizeof(struct ata_xfer));
- }
- xfer->c_slot = -1;
return xfer;
}
void
ata_free_xfer(struct ata_channel *chp, struct ata_xfer *xfer)
{
- struct atac_softc *atac = chp->ch_atac;
+ struct ata_queue *chq = chp->ch_queue;
int s;
if (xfer->c_flags & C_WAITACT) {
@@ -1126,10 +1101,9 @@
}
#endif
- if (atac->atac_free_hw)
- (*atac->atac_free_hw)(chp);
s = splbio();
- pool_put(&ata_xfer_pool, xfer);
+ KASSERT((chq->queue_xfers_avail & __BIT(xfer->c_slot)) == 0);
+ chq->queue_xfers_avail |= __BIT(xfer->c_slot);
splx(s);
}
@@ -1138,13 +1112,12 @@
{
struct ata_queue * const chq = chp->ch_queue;
- KASSERT(xfer->c_slot >= 0);
KASSERT(chq->queue_active < chq->queue_openings);
- KASSERT(chq->active_xfers[xfer->c_slot] == NULL);
+ KASSERT((chq->queue_xfers_avail & __BIT(xfer->c_slot)) == 0);
TAILQ_REMOVE(&chq->queue_xfer, xfer, c_xferchain);
+ TAILQ_INSERT_TAIL(&chq->active_xfers, xfer, c_activechain);
- chq->active_xfers[xfer->c_slot] = xfer;
chq->queue_active++;
}
@@ -1153,17 +1126,14 @@
{
struct ata_queue * const chq = chp->ch_queue;
- KASSERT(xfer->c_slot >= 0);
KASSERT(chq->queue_active > 0);
- KASSERT(chq->active_xfers[xfer->c_slot] == xfer);
+ KASSERT((chq->queue_xfers_avail & __BIT(xfer->c_slot)) == 0);
//if ((xfer->c_flags & C_TIMEOU) == 0)
callout_stop(&chp->ch_callout);
- chq->active_xfers[xfer->c_slot] = NULL;
+ TAILQ_REMOVE(&chq->active_xfers, xfer, c_activechain);
chq->queue_active--;
-
- xfer->c_slot = -1;
}
@@ -1172,7 +1142,7 @@
{
if (chp->ch_drive[drive].drive_flags & ATA_DRIVE_WAITDRAIN) {
chp->ch_drive[drive].drive_flags &= ~ATA_DRIVE_WAITDRAIN;
- wakeup(chp->ch_queue->active_xfers);
+ wakeup(&chp->ch_queue->active_xfers);
return true;
}
return false;
@@ -1185,7 +1155,7 @@
if (chp->ch_drive[drive].drive_flags & ATA_DRIVE_WAITDRAIN) {
(*xfer->c_kill_xfer)(chp, xfer, KILL_GONE);
chp->ch_drive[drive].drive_flags &= ~ATA_DRIVE_WAITDRAIN;
- wakeup(chp->ch_queue->active_xfers);
+ wakeup(&chp->ch_queue->active_xfers);
return true;
}
return false;
@@ -1200,12 +1170,10 @@
ata_kill_active(struct ata_channel *chp, int reason)
{
struct ata_queue * const chq = chp->ch_queue;
- for (u_int i = 0;
- chq->queue_active > 0 && i < chq->queue_openings; i++) {
- struct ata_xfer *xfer = chq->active_xfers[i];
- if (xfer != NULL) {
- (*xfer->c_kill_xfer)(xfer->c_chp, xfer, reason);
- }
+ struct ata_xfer *xfer, *xfernext;
+
+ TAILQ_FOREACH_SAFE(xfer, &chq->active_xfers, c_activechain, xfernext) {
+ (*xfer->c_kill_xfer)(xfer->c_chp, xfer, reason);
}
}
@@ -1233,12 +1201,13 @@
while (chq->queue_active > 0) {
if (chq->queue_openings == 1 && chp->ch_ndrives > 1) {
- xfer = chq->active_xfers[0];
+ xfer = TAILQ_FIRST(&chq->active_xfers);
+ KASSERT(xfer != NULL);
if (xfer->c_chp != chp || xfer->c_drive != drvp->drive)
break;
}
drvp->drive_flags |= ATA_DRIVE_WAITDRAIN;
- (void) tsleep(&chq->active_xfers[0], PRIBIO, "atdrn", 0);
+ (void) tsleep(&chq->active_xfers, PRIBIO, "atdrn", 0);
}
splx(s);
}
diff -r 3735afc630e5 -r 3841969bc5c3 sys/dev/ata/ata_wdc.c
--- a/sys/dev/ata/ata_wdc.c Wed Apr 12 22:28:20 2017 +0000
+++ b/sys/dev/ata/ata_wdc.c Sat Apr 15 12:01:23 2017 +0000
@@ -1,4 +1,4 @@
Home |
Main Index |
Thread Index |
Old Index