Add posixshmcontrol(1) support for largepage shm objects.

Create op with -l <largepage> option can create it, stat displays
configured page size.

Reviewed by:	markj
Tested by:	pho
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D24652
This commit is contained in:
Konstantin Belousov 2020-09-09 22:22:02 +00:00
parent 3ef55e8f25
commit 19fabdb70c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=365525

View File

@ -30,8 +30,10 @@
__FBSDID("$FreeBSD$"); __FBSDID("$FreeBSD$");
#include <sys/param.h> #include <sys/param.h>
#include <sys/filio.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/sysctl.h> #include <sys/sysctl.h>
#include <sys/user.h> #include <sys/user.h>
#include <err.h> #include <err.h>
@ -50,7 +52,7 @@ usage(void)
{ {
fprintf(stderr, "Usage:\n" fprintf(stderr, "Usage:\n"
"posixshmcontrol create [-m <mode>] <path> ...\n" "posixshmcontrol create [-m <mode>] [-l <largepage>] <path> ...\n"
"posixshmcontrol rm <path> ...\n" "posixshmcontrol rm <path> ...\n"
"posixshmcontrol ls [-h] [-n]\n" "posixshmcontrol ls [-h] [-n]\n"
"posixshmcontrol dump <path> ...\n" "posixshmcontrol dump <path> ...\n"
@ -59,15 +61,24 @@ usage(void)
} }
static int static int
create_one_shm(const char *path, long mode) create_one_shm(const char *path, long mode, int idx)
{ {
int fd; int fd;
if (idx == -1) {
fd = shm_open(path, O_RDWR | O_CREAT, mode); fd = shm_open(path, O_RDWR | O_CREAT, mode);
if (fd == -1) { if (fd == -1) {
warn("create %s", path); warn("create %s", path);
return (1); return (1);
} }
} else {
fd = shm_create_largepage(path, O_RDWR, idx,
SHM_LARGEPAGE_ALLOC_DEFAULT, mode);
if (fd == -1) {
warn("shm_create_largepage %s psind %d", path, idx);
return (1);
}
}
close(fd); close(fd);
return (0); return (0);
} }
@ -76,20 +87,60 @@ static int
create_shm(int argc, char **argv) create_shm(int argc, char **argv)
{ {
char *end; char *end;
size_t *pagesizes;
long mode; long mode;
int c, i, ret, ret1; uint64_t pgsz;
int c, i, idx, pn, ret, ret1;
bool printed;
mode = 0600; mode = 0600;
while ((c = getopt(argc, argv, "m:")) != -1) { idx = -1;
while ((c = getopt(argc, argv, "l:m:")) != -1) {
switch (c) { switch (c) {
case 'm': case 'm':
errno = 0; errno = 0;
mode = strtol(optarg, &end, 0); mode = strtol(optarg, &end, 0);
if (mode == 0 && errno != 0) if (mode == 0 && errno != 0)
err(1, "mode:"); err(1, "mode");
if (*end != '\0') if (*end != '\0')
errx(1, "non-integer mode"); errx(1, "non-integer mode");
break; break;
case 'l':
if (expand_number(optarg, &pgsz) == -1)
err(1, "size");
pn = getpagesizes(NULL, 0);
if (pn == -1)
err(1, "getpagesizes");
pagesizes = malloc(sizeof(size_t) * pn);
if (pagesizes == NULL)
err(1, "malloc");
if (getpagesizes(pagesizes, pn) == -1)
err(1, "gtpagesizes");
for (idx = 0; idx < pn; idx++) {
if (pagesizes[idx] == pgsz)
break;
}
if (idx == pn) {
fprintf(stderr,
"pagesize should be superpagesize, supported sizes:");
printed = false;
for (i = 0; i < pn; i++) {
if (pagesizes[i] == 0 ||
pagesizes[i] == (size_t)
getpagesize())
continue;
printed = true;
fprintf(stderr, " %zu", pagesizes[i]);
}
if (!printed)
fprintf(stderr, " none");
fprintf(stderr, "\n");
exit(1);
}
if (pgsz == (uint64_t)getpagesize())
errx(1, "pagesize should be large");
free(pagesizes);
break;
case '?': case '?':
default: default:
usage(); usage();
@ -101,7 +152,7 @@ create_shm(int argc, char **argv)
argv += optind; argv += optind;
ret = 0; ret = 0;
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
ret1 = create_one_shm(argv[i], mode); ret1 = create_one_shm(argv[i], mode, idx);
if (ret1 != 0 && ret == 0) if (ret1 != 0 && ret == 0)
ret = ret1; ret = ret1;
} }
@ -349,6 +400,9 @@ stat_one_shm(const char *path, bool hsize, bool uname)
(long)st.st_ctim.tv_nsec); (long)st.st_ctim.tv_nsec);
printf("birth\t%ld.%09ld\n", (long)st.st_birthtim.tv_sec, printf("birth\t%ld.%09ld\n", (long)st.st_birthtim.tv_sec,
(long)st.st_birthtim.tv_nsec); (long)st.st_birthtim.tv_nsec);
if (st.st_blocks != 0)
printf("pagesz\t%jd\n", roundup((uintmax_t)st.st_size,
PAGE_SIZE) / st.st_blocks);
} }
close(fd); close(fd);
return (ret); return (ret);