shmfd: account for the actually allocated pages
Return the value as stat(2) st_blocks. Suggested and reviewed by: markj (previous version) Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D37097
This commit is contained in:
parent
37aea2649f
commit
0919f29d91
@ -347,6 +347,61 @@ shm_largepage(struct shmfd *shmfd)
|
|||||||
return (shmfd->shm_object->type == OBJT_PHYS);
|
return (shmfd->shm_object->type == OBJT_PHYS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
shm_pager_freespace(vm_object_t obj, vm_pindex_t start, vm_size_t size)
|
||||||
|
{
|
||||||
|
struct shmfd *shm;
|
||||||
|
vm_size_t c;
|
||||||
|
|
||||||
|
swap_pager_freespace(obj, start, size, &c);
|
||||||
|
if (c == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
shm = obj->un_pager.swp.swp_priv;
|
||||||
|
if (shm == NULL)
|
||||||
|
return;
|
||||||
|
KASSERT(shm->shm_pages >= c,
|
||||||
|
("shm %p pages %jd free %jd", shm,
|
||||||
|
(uintmax_t)shm->shm_pages, (uintmax_t)c));
|
||||||
|
shm->shm_pages -= c;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
shm_page_inserted(vm_object_t obj, vm_page_t m)
|
||||||
|
{
|
||||||
|
struct shmfd *shm;
|
||||||
|
|
||||||
|
shm = obj->un_pager.swp.swp_priv;
|
||||||
|
if (shm == NULL)
|
||||||
|
return;
|
||||||
|
if (!vm_pager_has_page(obj, m->pindex, NULL, NULL))
|
||||||
|
shm->shm_pages += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
shm_page_removed(vm_object_t obj, vm_page_t m)
|
||||||
|
{
|
||||||
|
struct shmfd *shm;
|
||||||
|
|
||||||
|
shm = obj->un_pager.swp.swp_priv;
|
||||||
|
if (shm == NULL)
|
||||||
|
return;
|
||||||
|
if (!vm_pager_has_page(obj, m->pindex, NULL, NULL)) {
|
||||||
|
KASSERT(shm->shm_pages >= 1,
|
||||||
|
("shm %p pages %jd free 1", shm,
|
||||||
|
(uintmax_t)shm->shm_pages));
|
||||||
|
shm->shm_pages -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct pagerops shm_swap_pager_ops = {
|
||||||
|
.pgo_kvme_type = KVME_TYPE_SWAP,
|
||||||
|
.pgo_freespace = shm_pager_freespace,
|
||||||
|
.pgo_page_inserted = shm_page_inserted,
|
||||||
|
.pgo_page_removed = shm_page_removed,
|
||||||
|
};
|
||||||
|
static int shmfd_pager_type = -1;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
shm_seek(struct file *fp, off_t offset, int whence, struct thread *td)
|
shm_seek(struct file *fp, off_t offset, int whence, struct thread *td)
|
||||||
{
|
{
|
||||||
@ -563,7 +618,6 @@ shm_stat(struct file *fp, struct stat *sb, struct ucred *active_cred)
|
|||||||
bzero(sb, sizeof(*sb));
|
bzero(sb, sizeof(*sb));
|
||||||
sb->st_blksize = PAGE_SIZE;
|
sb->st_blksize = PAGE_SIZE;
|
||||||
sb->st_size = shmfd->shm_size;
|
sb->st_size = shmfd->shm_size;
|
||||||
sb->st_blocks = howmany(sb->st_size, sb->st_blksize);
|
|
||||||
mtx_lock(&shm_timestamp_lock);
|
mtx_lock(&shm_timestamp_lock);
|
||||||
sb->st_atim = shmfd->shm_atime;
|
sb->st_atim = shmfd->shm_atime;
|
||||||
sb->st_ctim = shmfd->shm_ctime;
|
sb->st_ctim = shmfd->shm_ctime;
|
||||||
@ -576,8 +630,12 @@ shm_stat(struct file *fp, struct stat *sb, struct ucred *active_cred)
|
|||||||
sb->st_dev = shm_dev_ino;
|
sb->st_dev = shm_dev_ino;
|
||||||
sb->st_ino = shmfd->shm_ino;
|
sb->st_ino = shmfd->shm_ino;
|
||||||
sb->st_nlink = shmfd->shm_object->ref_count;
|
sb->st_nlink = shmfd->shm_object->ref_count;
|
||||||
sb->st_blocks = shmfd->shm_object->size /
|
if (shm_largepage(shmfd)) {
|
||||||
(pagesizes[shmfd->shm_lp_psind] >> PAGE_SHIFT);
|
sb->st_blocks = shmfd->shm_object->size /
|
||||||
|
(pagesizes[shmfd->shm_lp_psind] >> PAGE_SHIFT);
|
||||||
|
} else {
|
||||||
|
sb->st_blocks = shmfd->shm_pages;
|
||||||
|
}
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -876,6 +934,7 @@ struct shmfd *
|
|||||||
shm_alloc(struct ucred *ucred, mode_t mode, bool largepage)
|
shm_alloc(struct ucred *ucred, mode_t mode, bool largepage)
|
||||||
{
|
{
|
||||||
struct shmfd *shmfd;
|
struct shmfd *shmfd;
|
||||||
|
vm_object_t obj;
|
||||||
|
|
||||||
shmfd = malloc(sizeof(*shmfd), M_SHMFD, M_WAITOK | M_ZERO);
|
shmfd = malloc(sizeof(*shmfd), M_SHMFD, M_WAITOK | M_ZERO);
|
||||||
shmfd->shm_size = 0;
|
shmfd->shm_size = 0;
|
||||||
@ -888,8 +947,12 @@ shm_alloc(struct ucred *ucred, mode_t mode, bool largepage)
|
|||||||
VM_PROT_DEFAULT, 0, ucred);
|
VM_PROT_DEFAULT, 0, ucred);
|
||||||
shmfd->shm_lp_alloc_policy = SHM_LARGEPAGE_ALLOC_DEFAULT;
|
shmfd->shm_lp_alloc_policy = SHM_LARGEPAGE_ALLOC_DEFAULT;
|
||||||
} else {
|
} else {
|
||||||
shmfd->shm_object = vm_pager_allocate(OBJT_SWAP, NULL,
|
obj = vm_pager_allocate(shmfd_pager_type, NULL,
|
||||||
shmfd->shm_size, VM_PROT_DEFAULT, 0, ucred);
|
shmfd->shm_size, VM_PROT_DEFAULT, 0, ucred);
|
||||||
|
VM_OBJECT_WLOCK(obj);
|
||||||
|
obj->un_pager.swp.swp_priv = shmfd;
|
||||||
|
VM_OBJECT_WUNLOCK(obj);
|
||||||
|
shmfd->shm_object = obj;
|
||||||
}
|
}
|
||||||
KASSERT(shmfd->shm_object != NULL, ("shm_create: vm_pager_allocate"));
|
KASSERT(shmfd->shm_object != NULL, ("shm_create: vm_pager_allocate"));
|
||||||
vfs_timestamp(&shmfd->shm_birthtime);
|
vfs_timestamp(&shmfd->shm_birthtime);
|
||||||
@ -918,6 +981,7 @@ shm_hold(struct shmfd *shmfd)
|
|||||||
void
|
void
|
||||||
shm_drop(struct shmfd *shmfd)
|
shm_drop(struct shmfd *shmfd)
|
||||||
{
|
{
|
||||||
|
vm_object_t obj;
|
||||||
|
|
||||||
if (refcount_release(&shmfd->shm_refs)) {
|
if (refcount_release(&shmfd->shm_refs)) {
|
||||||
#ifdef MAC
|
#ifdef MAC
|
||||||
@ -925,7 +989,13 @@ shm_drop(struct shmfd *shmfd)
|
|||||||
#endif
|
#endif
|
||||||
rangelock_destroy(&shmfd->shm_rl);
|
rangelock_destroy(&shmfd->shm_rl);
|
||||||
mtx_destroy(&shmfd->shm_mtx);
|
mtx_destroy(&shmfd->shm_mtx);
|
||||||
vm_object_deallocate(shmfd->shm_object);
|
obj = shmfd->shm_object;
|
||||||
|
if (!shm_largepage(shmfd)) {
|
||||||
|
VM_OBJECT_WLOCK(obj);
|
||||||
|
obj->un_pager.swp.swp_priv = NULL;
|
||||||
|
VM_OBJECT_WUNLOCK(obj);
|
||||||
|
}
|
||||||
|
vm_object_deallocate(obj);
|
||||||
free(shmfd, M_SHMFD);
|
free(shmfd, M_SHMFD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -964,6 +1034,9 @@ shm_init(void *arg)
|
|||||||
new_unrhdr64(&shm_ino_unr, 1);
|
new_unrhdr64(&shm_ino_unr, 1);
|
||||||
shm_dev_ino = devfs_alloc_cdp_inode();
|
shm_dev_ino = devfs_alloc_cdp_inode();
|
||||||
KASSERT(shm_dev_ino > 0, ("shm dev inode not initialized"));
|
KASSERT(shm_dev_ino > 0, ("shm dev inode not initialized"));
|
||||||
|
shmfd_pager_type = vm_pager_alloc_dyn_type(&shm_swap_pager_ops,
|
||||||
|
OBJT_SWAP);
|
||||||
|
MPASS(shmfd_pager_type != -1);
|
||||||
|
|
||||||
for (i = 1; i < MAXPAGESIZES; i++) {
|
for (i = 1; i < MAXPAGESIZES; i++) {
|
||||||
if (pagesizes[i] == 0)
|
if (pagesizes[i] == 0)
|
||||||
|
@ -268,6 +268,7 @@ struct file;
|
|||||||
struct shmfd {
|
struct shmfd {
|
||||||
vm_ooffset_t shm_size;
|
vm_ooffset_t shm_size;
|
||||||
vm_object_t shm_object;
|
vm_object_t shm_object;
|
||||||
|
vm_pindex_t shm_pages; /* allocated pages */
|
||||||
int shm_refs;
|
int shm_refs;
|
||||||
uid_t shm_uid;
|
uid_t shm_uid;
|
||||||
gid_t shm_gid;
|
gid_t shm_gid;
|
||||||
|
Loading…
Reference in New Issue
Block a user