Optimize the size of the work-items by letting the mapping function
decide the largest size which stays inside the zone and does not collide with a lock sector.
This commit is contained in:
parent
777cc88b9d
commit
acb161b16f
@ -161,7 +161,7 @@ void g_bde_hash_pass(struct g_bde_softc *sc, const void *input, u_int len);
|
||||
|
||||
/* g_bde_math .c */
|
||||
uint64_t g_bde_max_sector(struct g_bde_key *lp);
|
||||
void g_bde_map_sector(struct g_bde_key *lp, uint64_t isector, uint64_t *osector, uint64_t *ksector, u_int *koffset);
|
||||
void g_bde_map_sector(struct g_bde_work *wp);
|
||||
|
||||
/* g_bde_work.c */
|
||||
void g_bde_start1(struct bio *bp);
|
||||
|
@ -245,8 +245,13 @@ g_bde_max_sector(struct g_bde_key *kp)
|
||||
* on a "cold" disk image.
|
||||
*
|
||||
* We do this by adding the "keyoffset" from the lock to the physical sector
|
||||
* number modulus the available number of sectors, since all physical sectors
|
||||
* presumably look the same cold, this should be enough.
|
||||
* number modulus the available number of sectors. Since all physical sectors
|
||||
* presumably look the same cold, this will do.
|
||||
*
|
||||
* As part of the mapping we have to skip the lock sectors which we know
|
||||
* the physical address off. We also truncate the work packet, respecting
|
||||
* zone boundaries and lock sectors, so that we end up with a sequence of
|
||||
* sectors which are physically contiguous.
|
||||
*
|
||||
* Shuffling things further is an option, but the incremental frustration is
|
||||
* not currently deemed worth the run-time performance hit resulting from the
|
||||
@ -257,52 +262,64 @@ g_bde_max_sector(struct g_bde_key *kp)
|
||||
*/
|
||||
|
||||
void
|
||||
g_bde_map_sector(struct g_bde_key *kp,
|
||||
uint64_t isector,
|
||||
uint64_t *osector,
|
||||
uint64_t *ksector,
|
||||
u_int *koffset)
|
||||
g_bde_map_sector(struct g_bde_work *wp)
|
||||
{
|
||||
|
||||
u_int zone, zoff, zidx, u;
|
||||
uint64_t os;
|
||||
u_int zone, zoff, u, len;
|
||||
uint64_t ko;
|
||||
struct g_bde_softc *sc;
|
||||
struct g_bde_key *kp;
|
||||
|
||||
/* find which zone and the offset and index in it */
|
||||
zone = isector / kp->zone_cont;
|
||||
zoff = isector % kp->zone_cont;
|
||||
zidx = zoff / kp->sectorsize;
|
||||
sc = wp->softc;
|
||||
kp = &sc->key;
|
||||
|
||||
/* find which zone and the offset in it */
|
||||
zone = wp->offset / kp->zone_cont;
|
||||
zoff = wp->offset % kp->zone_cont;
|
||||
|
||||
/* Calculate the offset of the key in the key sector */
|
||||
wp->ko = (zoff / kp->sectorsize) * G_BDE_SKEYLEN;
|
||||
|
||||
/* restrict length to that zone */
|
||||
len = kp->zone_cont - zoff;
|
||||
if (len < wp->length)
|
||||
wp->length = len;
|
||||
|
||||
/* Find physical sector address */
|
||||
os = zone * kp->zone_width + zoff;
|
||||
os += kp->keyoffset;
|
||||
os %= kp->media_width;
|
||||
os += kp->sector0;
|
||||
|
||||
/* Compensate for lock sectors */
|
||||
for (u = 0; u < G_BDE_MAXKEYS; u++)
|
||||
if (os >= (kp->lsector[u] & ~(kp->sectorsize - 1)))
|
||||
os += kp->sectorsize;
|
||||
|
||||
*osector = os;
|
||||
wp->so = zone * kp->zone_width + zoff;
|
||||
wp->so += kp->keyoffset;
|
||||
wp->so %= kp->media_width;
|
||||
wp->so += kp->sector0;
|
||||
|
||||
/* The key sector is the last in this zone. */
|
||||
os = (1 + zone) * kp->zone_width - kp->sectorsize;
|
||||
os += kp->keyoffset;
|
||||
os %= kp->media_width;
|
||||
os += kp->sector0;
|
||||
wp->kso = zone * kp->zone_width + kp->zone_cont;
|
||||
wp->kso += kp->keyoffset;
|
||||
wp->kso %= kp->media_width;
|
||||
wp->kso += kp->sector0;
|
||||
|
||||
for (u = 0; u < G_BDE_MAXKEYS; u++)
|
||||
if (os >= (kp->lsector[u] & ~(kp->sectorsize - 1)))
|
||||
os += kp->sectorsize;
|
||||
*ksector = os;
|
||||
/* Compensate for lock sectors */
|
||||
for (u = 0; u < G_BDE_MAXKEYS; u++) {
|
||||
/* Find the start of this lock sector */
|
||||
ko = kp->lsector[u] & ~(kp->sectorsize - 1);
|
||||
|
||||
*koffset = zidx * G_BDE_SKEYLEN;
|
||||
if (wp->kso >= ko)
|
||||
wp->kso += kp->sectorsize;
|
||||
|
||||
if (wp->so >= ko) {
|
||||
/* lock sector before work packet */
|
||||
wp->so += kp->sectorsize;
|
||||
} else if ((wp->so + wp->length) > ko) {
|
||||
/* lock sector in work packet, truncate */
|
||||
wp->length = ko - wp->so;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
printf("off %jd %jd %jd %u\n",
|
||||
(intmax_t)isector,
|
||||
(intmax_t)*osector,
|
||||
(intmax_t)*ksector,
|
||||
*koffset);
|
||||
printf("off %jd len %jd so %jd ko %jd kso %u\n",
|
||||
(intmax_t)wp->offset,
|
||||
(intmax_t)wp->length,
|
||||
(intmax_t)wp->so,
|
||||
(intmax_t)wp->kso,
|
||||
wp->ko);
|
||||
#endif
|
||||
}
|
||||
|
@ -651,10 +651,9 @@ g_bde_start2(struct g_bde_work *wp)
|
||||
struct g_bde_softc *sc;
|
||||
|
||||
KASSERT(wp != NULL, ("NULL wp in g_bde_start2"));
|
||||
KASSERT(wp->softc != NULL, ("NULL wp->softc"));
|
||||
g_trace(G_T_TOPOLOGY, "g_bde_start2(%p)", wp);
|
||||
sc = wp->softc;
|
||||
KASSERT(wp->softc != NULL, ("NULL wp->softc"));
|
||||
g_bde_map_sector(&sc->key, wp->offset, &wp->so, &wp->kso, &wp->ko);
|
||||
if (wp->bp->bio_cmd == BIO_READ) {
|
||||
wp->sp = g_bde_new_sector(wp, 0);
|
||||
if (wp->sp == NULL) {
|
||||
@ -704,8 +703,8 @@ g_bde_start2(struct g_bde_work *wp)
|
||||
}
|
||||
|
||||
/*
|
||||
* Split the incoming bio on zone boundaries and submit the resulting
|
||||
* work structures to g_bde_start2().
|
||||
* Create a sequence of work structures, and have g_bde_map_sector() determine
|
||||
* how long they each can be. Feed them to g_bde_start2().
|
||||
*/
|
||||
|
||||
void
|
||||
@ -713,13 +712,13 @@ g_bde_start1(struct bio *bp)
|
||||
{
|
||||
struct g_bde_softc *sc;
|
||||
struct g_bde_work *wp;
|
||||
off_t left;
|
||||
off_t done;
|
||||
|
||||
sc = bp->bio_to->geom->softc;
|
||||
bp->bio_driver1 = sc;
|
||||
|
||||
mtx_lock(&sc->worklist_mutex);
|
||||
for(left = 0;left < bp->bio_length; left += sc->sectorsize) {
|
||||
for(done = 0; done < bp->bio_length; ) {
|
||||
wp = g_bde_new_work(sc);
|
||||
if (wp == NULL) {
|
||||
g_io_deliver(bp, ENOMEM);
|
||||
@ -727,9 +726,11 @@ g_bde_start1(struct bio *bp)
|
||||
return;
|
||||
}
|
||||
wp->bp = bp;
|
||||
wp->offset = bp->bio_offset + left;
|
||||
wp->data = bp->bio_data + left;
|
||||
wp->length = sc->sectorsize;
|
||||
wp->offset = bp->bio_offset + done;
|
||||
wp->data = bp->bio_data + done;
|
||||
wp->length = bp->bio_length - done;
|
||||
g_bde_map_sector(wp);
|
||||
done += wp->length;
|
||||
g_bde_start2(wp);
|
||||
}
|
||||
mtx_unlock(&sc->worklist_mutex);
|
||||
|
Loading…
x
Reference in New Issue
Block a user