Changeset View
Standalone View
sys/kern/uipc_shm.c
Show First 20 Lines • Show All 132 Lines • ▼ Show 20 Lines | |||||
static fo_close_t shm_close; | static fo_close_t shm_close; | ||||
static fo_chmod_t shm_chmod; | static fo_chmod_t shm_chmod; | ||||
static fo_chown_t shm_chown; | static fo_chown_t shm_chown; | ||||
static fo_seek_t shm_seek; | static fo_seek_t shm_seek; | ||||
static fo_fill_kinfo_t shm_fill_kinfo; | static fo_fill_kinfo_t shm_fill_kinfo; | ||||
static fo_mmap_t shm_mmap; | static fo_mmap_t shm_mmap; | ||||
static fo_get_seals_t shm_get_seals; | static fo_get_seals_t shm_get_seals; | ||||
static fo_add_seals_t shm_add_seals; | static fo_add_seals_t shm_add_seals; | ||||
static fo_fallocate_t shm_fallocate; | |||||
/* File descriptor operations. */ | /* File descriptor operations. */ | ||||
struct fileops shm_ops = { | struct fileops shm_ops = { | ||||
.fo_read = shm_read, | .fo_read = shm_read, | ||||
.fo_write = shm_write, | .fo_write = shm_write, | ||||
.fo_truncate = shm_truncate, | .fo_truncate = shm_truncate, | ||||
.fo_ioctl = shm_ioctl, | .fo_ioctl = shm_ioctl, | ||||
.fo_poll = invfo_poll, | .fo_poll = invfo_poll, | ||||
.fo_kqfilter = invfo_kqfilter, | .fo_kqfilter = invfo_kqfilter, | ||||
.fo_stat = shm_stat, | .fo_stat = shm_stat, | ||||
.fo_close = shm_close, | .fo_close = shm_close, | ||||
.fo_chmod = shm_chmod, | .fo_chmod = shm_chmod, | ||||
.fo_chown = shm_chown, | .fo_chown = shm_chown, | ||||
.fo_sendfile = vn_sendfile, | .fo_sendfile = vn_sendfile, | ||||
.fo_seek = shm_seek, | .fo_seek = shm_seek, | ||||
.fo_fill_kinfo = shm_fill_kinfo, | .fo_fill_kinfo = shm_fill_kinfo, | ||||
.fo_mmap = shm_mmap, | .fo_mmap = shm_mmap, | ||||
.fo_get_seals = shm_get_seals, | .fo_get_seals = shm_get_seals, | ||||
.fo_add_seals = shm_add_seals, | .fo_add_seals = shm_add_seals, | ||||
.fo_fallocate = shm_fallocate, | |||||
.fo_flags = DFLAG_PASSABLE | DFLAG_SEEKABLE | .fo_flags = DFLAG_PASSABLE | DFLAG_SEEKABLE | ||||
}; | }; | ||||
FEATURE(posix_shm, "POSIX shared memory"); | FEATURE(posix_shm, "POSIX shared memory"); | ||||
static int | static int | ||||
uiomove_object_page(vm_object_t obj, size_t len, struct uio *uio) | uiomove_object_page(vm_object_t obj, size_t len, struct uio *uio) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 1,262 Lines • ▼ Show 20 Lines | |||||
static int | static int | ||||
shm_get_seals(struct file *fp, int *seals) | shm_get_seals(struct file *fp, int *seals) | ||||
{ | { | ||||
struct shmfd *shmfd; | struct shmfd *shmfd; | ||||
shmfd = fp->f_data; | shmfd = fp->f_data; | ||||
*seals = shmfd->shm_seals; | *seals = shmfd->shm_seals; | ||||
return (0); | return (0); | ||||
} | |||||
static int | |||||
shm_fallocate(struct file *fp, off_t offset, off_t len, struct thread *td) | |||||
{ | |||||
struct shmfd *shmfd; | |||||
size_t size; | |||||
int error; | |||||
/* This assumes that the caller already checked for overflow. */ | |||||
error = 0; | |||||
shmfd = fp->f_data; | |||||
size = offset + len; | |||||
if (size > shmfd->shm_size) | |||||
error = shm_dotruncate(shmfd, size); | |||||
/* Translate to posix_fallocate(2) return value as needed. */ | |||||
if (error == ENOMEM) | |||||
error = ENOSPC; | |||||
return (error); | |||||
} | } | ||||
kib: Does it make sense to instantiate pages for the fallocated range ? Even if it does, I suggest… | |||||
Done Inline ActionsThis wasn't clear to me- the wording on the spec (which our manpage seems to basically copy) carefully avoids making any promises on the state of any newly allocated space kevans: This wasn't clear to me- the wording on the spec (which our manpage seems to basically copy)… | |||||
Not Done Inline ActionsThis is because the only way to guarantee that the pages are not get recycled is to wire them. But if the intent is to provide the backing storage so that later the app would not pay the allocation cost, e.g. by waiting for pages to become available, then pages should be allocated. I do not know what is the use case for fallocate() over shmfd. kib: This is because the only way to guarantee that the pages are not get recycled is to wire them. | |||||
Not Done Inline Actions
Examples:
The intent in the Weston code that ended up in many places was "to guarantee that disk space is available for the file at the given size"… even if the file is purely in-memory. It's code that was written assuming on-disk /tmp first, with memfd/SHM_ANON bolted on later. [[ https://gitlab.freedesktop.org/mesa/mesa/blob/642125edd97384b88f491c1383a06c42ed16e11e/src/util/anon_file.c#L97-158 | In Mesa, we don't use posix_fallocate anymore ]]. So it's relatively safe to assume that fallocate is used as just a "better" ftruncate here. val_packett.cool: > I do not know what is the use case for fallocate() over shmfd
Examples:
* https://gitlab. | |||||
Done Inline ActionsThanks for the insight! kevans: Thanks for the insight! | |||||
static int | static int | ||||
sysctl_posix_shm_list(SYSCTL_HANDLER_ARGS) | sysctl_posix_shm_list(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
struct shm_mapping *shmm; | struct shm_mapping *shmm; | ||||
struct sbuf sb; | struct sbuf sb; | ||||
struct kinfo_file kif; | struct kinfo_file kif; | ||||
u_long i; | u_long i; | ||||
▲ Show 20 Lines • Show All 63 Lines • Show Last 20 Lines |
Does it make sense to instantiate pages for the fallocated range ? Even if it does, I suggest to do it in the follow-up commit.