http://perforce.freebsd.org/chv.cgi?CH=60012 Change 60012 by pjd@pjd_anger on 2004/08/18 21:23:00 - Avoid many, many memory allocations. Just allocate data once per whole synchronization process, not per every I/O. - Increase size of synchronization I/O to 128kB - we can do this, because we don't use g_read_data(9) anymore. --- //depot/vendor/freebsd/src/sys/geom/vinum/geom_vinum_init.c 2004/08/18 20:45:30 +++ //depot/user/pjd/geom_classes/sys/geom/vinum/geom_vinum_init.c 2004/08/18 21:23:00 @@ -261,57 +261,65 @@ printf("GEOM_VINUM: plex sync %s -> %s started\n", sync->from->name, sync->to->name); + buf = NULL; + bp = g_new_bio(); + if (bp == NULL) { + error = ENOMEM; + printf("gvinum: sync of '%s' failed, no memory\n", p->name); + goto end; + } + bp->bio_done = NULL; + bp->bio_length = sync->syncsize; + /* + * This hack declare this bio as part of an initialization + * process, so that the lower levels allow it to get through. + */ + bp->bio_caller1 = p; + buf = g_malloc(sync->syncsize, M_WAITOK); + bp->bio_data = buf; for (i = 0; i < p->size; i+= sync->syncsize) { /* Read some bits from the good plex. */ - buf = g_read_data(from, i, sync->syncsize, &error); - if (buf == NULL) { + bp->bio_cmd = BIO_READ; + bp->bio_offset = i; + bp->bio_length = MIN(sync->syncsize, p->size - i); + bp->bio_completed = 0; + + /* Schedule it down ... */ + g_io_request(bp, from); + + /* ... and wait for the result. */ + error = biowait(bp, "gread"); + if (error != 0) { printf("gvinum: sync read from '%s' failed at offset " "%jd, errno: %d\n", sync->from->name, i, error); break; } /* - * Create a bio and schedule it down on the 'bad' plex. We - * cannot simply use g_write_data() because we have to let the - * lower parts know that we are an initialization process and - * not a 'normal' request. + * Write data to the 'bad' plex. */ - bp = g_new_bio(); - if (bp == NULL) { - printf("gvinum: sync write to '%s' failed at offset " - "%jd, out of memory\n", p->name, i); - g_free(buf); - break; - } bp->bio_cmd = BIO_WRITE; - bp->bio_offset = i; - bp->bio_length = sync->syncsize; - bp->bio_data = buf; - bp->bio_done = NULL; - - /* - * This hack declare this bio as part of an initialization - * process, so that the lower levels allow it to get through. - */ - bp->bio_caller1 = p; + bp->bio_completed = 0; /* Schedule it down ... */ g_io_request(bp, to); /* ... and wait for the result. */ error = biowait(bp, "gwrite"); - g_destroy_bio(bp); - g_free(buf); - if (error) { + if (error != 0) { printf("gvinum: sync write to '%s' failed at offset " "%jd, errno: %d\n", p->name, i, error); break; } /* Note that we have synced a little bit more. */ - p->synced += sync->syncsize; + p->synced += bp->bio_completed; } - +end: + if (buf != NULL) + g_free(buf); + if (bp != NULL) + g_destroy_bio(bp); g_topology_lock(); g_access(from, -1, 0, 0); g_access(to, 0, -1, 0); --- //depot/vendor/freebsd/src/sys/geom/vinum/geom_vinum_var.h 2004/06/12 21:20:40 +++ //depot/user/pjd/geom_classes/sys/geom/vinum/geom_vinum_var.h 2004/08/18 21:23:00 @@ -105,7 +105,7 @@ /* Synchronization/initialization request sizes. */ #define GV_MIN_SYNCSIZE 512 #define GV_MAX_SYNCSIZE MAXPHYS -#define GV_DFLT_SYNCSIZE 65536 +#define GV_DFLT_SYNCSIZE GV_MAX_SYNCSIZE /* * hostname is 256 bytes long, but we don't need to shlep multiple copies in