1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-30 12:04:07 +00:00

Use DEV_BSIZE byte sectors instead of PAGE_SIZE byte sectors for

swap-backed memory disks.  This reduces filesystem allocation overhead
and makes swap-backed memory disks compatible with broken code (dd,
for example) which expects to see 512 byte sectors.  The size of a
swap-backed memory disk must still be a multiple of the page size.

When performing page-aligned operations, this change has zero
performance impact.

Reviewed by:	phk
Approved by:	rwatson (mentor)
This commit is contained in:
Colin Percival 2004-02-29 15:58:54 +00:00
parent 5904b6fdcc
commit e07113d65c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=126408

View File

@ -168,6 +168,7 @@ struct md_s {
/* MD_SWAP related fields */
vm_object_t object;
unsigned npage;
};
static int mddestroy(struct md_s *sc, struct thread *td);
@ -520,20 +521,34 @@ static int
mdstart_swap(struct md_s *sc, struct bio *bp)
{
{
int i, o, rv;
int i, rv;
int offs, len, lastp, lastend;
vm_page_t m;
u_char *p;
vm_offset_t kva;
p = bp->bio_data;
o = bp->bio_offset / sc->secsize;
/*
* offs is the ofset at whih to start operating on the
* next (ie, first) page. lastp is the last page on
* which we're going to operate. lastend is the ending
* position within that last page (ie, PAGE_SIZE if
* we're operating on complete aligned pages).
*/
offs = bp->bio_offset % PAGE_SIZE;
lastp = (bp->bio_offset + bp->bio_length - 1) / PAGE_SIZE;
lastend = (bp->bio_offset + bp->bio_length - 1) % PAGE_SIZE + 1;
mtx_lock(&Giant);
kva = kmem_alloc_nofault(kernel_map, sc->secsize);
kva = kmem_alloc_nofault(kernel_map, PAGE_SIZE);
VM_OBJECT_LOCK(sc->object);
vm_object_pip_add(sc->object, 1);
for (i = 0; i < bp->bio_length / sc->secsize; i++) {
m = vm_page_grab(sc->object, i + o,
for (i = bp->bio_offset / PAGE_SIZE; i <= lastp; i++) {
len = ((i == lastp) ? lastend : PAGE_SIZE) - offs;
m = vm_page_grab(sc->object, i,
VM_ALLOC_NORMAL|VM_ALLOC_RETRY);
pmap_qenter(kva, &m, 1);
if (bp->bio_cmd == BIO_READ) {
@ -541,13 +556,23 @@ mdstart_swap(struct md_s *sc, struct bio *bp)
rv = vm_pager_get_pages(sc->object,
&m, 1, 0);
}
bcopy((void *)kva, p, sc->secsize);
bcopy((void *)(kva + offs), p, len);
} else if (bp->bio_cmd == BIO_WRITE) {
bcopy(p, (void *)kva, sc->secsize);
if (len != PAGE_SIZE && m->valid !=
VM_PAGE_BITS_ALL) {
rv = vm_pager_get_pages(sc->object,
&m, 1, 0);
}
bcopy(p, (void *)(kva + offs), len);
m->valid = VM_PAGE_BITS_ALL;
#if 0
} else if (bp->bio_cmd == BIO_DELETE) {
bzero((void *)kva, sc->secsize);
if (len != PAGE_SIZE && m->valid !=
VM_PAGE_BITS_ALL) {
rv = vm_pager_get_pages(sc->object,
&m, 1, 0);
}
bzero((void *)(kva + offs), len);
vm_page_dirty(m);
m->valid = VM_PAGE_BITS_ALL;
#endif
@ -560,12 +585,15 @@ mdstart_swap(struct md_s *sc, struct bio *bp)
vm_page_dirty(m);
}
vm_page_unlock_queues();
p += sc->secsize;
/* Actions on further pages start at offset 0 */
p += PAGE_SIZE - offs;
offs = 0;
#if 0
if (bootverbose || o < 17)
if (bootverbose || bp->bio_offset / PAGE_SIZE < 17)
printf("wire_count %d busy %d flags %x hold_count %d act_count %d queue %d valid %d dirty %d @ %d\n",
m->wire_count, m->busy,
m->flags, m->hold_count, m->act_count, m->queue, m->valid, m->dirty, o + i);
m->flags, m->hold_count, m->act_count, m->queue, m->valid, m->dirty, i);
#endif
}
vm_object_pip_subtract(sc->object, 1);
@ -1013,18 +1041,20 @@ mdcreate_swap(struct md_ioctl *mdio, struct thread *td)
/*
* Allocate an OBJT_SWAP object.
*
* sc_secsize is PAGE_SIZE'd
* sc_nsect is in units of DEV_BSIZE.
* sc_npage is in units of PAGE_SIZE.
*
* mdio->size is in DEV_BSIZE'd chunks.
* Note the truncation.
*/
sc->secsize = PAGE_SIZE;
sc->nsect = mdio->md_size / (PAGE_SIZE / DEV_BSIZE);
sc->object = vm_pager_allocate(OBJT_SWAP, NULL, sc->secsize * (vm_offset_t)sc->nsect, VM_PROT_DEFAULT, 0);
sc->secsize = DEV_BSIZE;
sc->npage = mdio->md_size / (PAGE_SIZE / DEV_BSIZE);
sc->nsect = sc->npage * (PAGE_SIZE / DEV_BSIZE);
sc->object = vm_pager_allocate(OBJT_SWAP, NULL, PAGE_SIZE *
(vm_offset_t)sc->npage, VM_PROT_DEFAULT, 0);
sc->flags = mdio->md_options & MD_FORCE;
if (mdio->md_options & MD_RESERVE) {
if (swap_pager_reserve(sc->object, 0, sc->nsect) < 0) {
if (swap_pager_reserve(sc->object, 0, sc->npage) < 0) {
vm_object_deallocate(sc->object);
sc->object = NULL;
mddestroy(sc, td);
@ -1122,7 +1152,7 @@ mdctlioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
mdio->md_base = (uint64_t)(intptr_t)sc->pl_ptr;
break;
case MD_SWAP:
mdio->md_size = sc->nsect * (PAGE_SIZE / DEV_BSIZE);
mdio->md_size = sc->nsect;
break;
case MD_VNODE:
mdio->md_size = sc->nsect;