Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/ic Rework the command queue, to avoid having command...
details: https://anonhg.NetBSD.org/src/rev/dab5b0c798e6
branches: trunk
changeset: 485772:dab5b0c798e6
user: bouyer <bouyer%NetBSD.org@localhost>
date: Fri May 05 09:05:44 2000 +0000
description:
Rework the command queue, to avoid having commands blocked at the end
of the queue. Load is now properly balanced across all disks of the same bus.
diffstat:
sys/dev/ic/siop.c | 47 ++++++++++++++++++++++++++++-------------------
1 files changed, 28 insertions(+), 19 deletions(-)
diffs (85 lines):
diff -r 0cb1b96b236e -r dab5b0c798e6 sys/dev/ic/siop.c
--- a/sys/dev/ic/siop.c Fri May 05 08:03:12 2000 +0000
+++ b/sys/dev/ic/siop.c Fri May 05 09:05:44 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: siop.c,v 1.9 2000/05/04 17:18:27 bouyer Exp $ */
+/* $NetBSD: siop.c,v 1.10 2000/05/05 09:05:44 bouyer Exp $ */
/*
* Copyright (c) 2000 Manuel Bouyer.
@@ -1587,7 +1587,7 @@
u_int32_t *scr;
u_int32_t dsa;
int timeout;
- int target, lun, slot, maxslot, maxslot0;
+ int target, lun, slot;
int newcmd = 0;
/*
@@ -1596,15 +1596,30 @@
siop_script_sync(sc, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
/*
- * we need to treat the slots as circular queue (to give a chance
- * to others commands to execute). So we have to remember the
- * last used slot in sc_currshedslot.
+ * The queue management here is a bit tricky: the script always looks
+ * at the slot from first to last, so if we always use the first
+ * free slot commands can stay at the tail of the queue ~forever.
+ * The algorithm used here is to restart from the head when we know
+ * that the queue is empty, and only add commands after the last one.
+ * When we're at the end of the queue wait for the script to clear it.
+ * The best thing to do here would be to implement a circular queue,
+ * but using only 53c720 features this can be "interesting".
+ * A mid-way solution could be to implement 2 queues and swap orders.
*/
- maxslot0 = sc->sc_currshedslot + 1;
- maxslot = sc->sc_nshedslots;
- slot = sc->sc_currshedslot + 1;
- if (slot >= sc->sc_nshedslots)
- sc->sc_currshedslot = slot = 0;
+ slot = sc->sc_currshedslot;
+ scr = &sc->sc_script[Ent_sheduler / 4 +
+ (Ent_nextslot / 4) * slot];
+ /*
+ * if relative addr of first jump is not 0 the slot is free. As this is
+ * the last used slot, all previous slots are free, we can restart
+ * from 0.
+ */
+ if (scr[Ent_slot / 4 + 1] != 0) {
+ slot = sc->sc_currshedslot = 0;
+ } else {
+ slot++;
+ }
+
for (target = 0; target <= sc->sc_link.scsipi_scsi.max_target;
target++) {
if (sc->targets[target] == NULL)
@@ -1618,8 +1633,7 @@
siop_cmd->status != CMDST_SENSE)
continue;
/* find a free sheduler slot and load it */
-retry:
- for (; slot < maxslot; slot++) {
+ for (; slot < sc->sc_nshedslots; slot++) {
scr = &sc->sc_script[Ent_sheduler / 4 +
(Ent_nextslot / 4) * slot];
/*
@@ -1682,15 +1696,10 @@
scr[Ent_slot / 4 + 1] = 0;
break;
}
- /* if we reached the end, restart at the beggining */
+ /* no more free slot, no need to continue */
if (slot == sc->sc_nshedslots) {
- slot = 0;
- maxslot = maxslot0;
- goto retry;
+ goto end;
}
- /* no more free slot, no need to continue */
- if (slot == sc->sc_currshedslot)
- goto end;
sc->sc_currshedslot = slot;
}
}
Home |
Main Index |
Thread Index |
Old Index