aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2020-09-09 22:22:02 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2020-09-09 22:22:02 +0000
commit19fabdb70c431678587cf3255aed216de2188efc (patch)
treed723b272c8a7fc511afff68e4bddfd090e4ee17a
parent3ef55e8f254c4e16b2e9f5a98849594ed564affd (diff)
downloadsrc-19fabdb70c431678587cf3255aed216de2188efc.tar.gz
src-19fabdb70c431678587cf3255aed216de2188efc.zip
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
Notes
Notes: svn path=/head/; revision=365525
-rw-r--r--usr.bin/posixshmcontrol/posixshmcontrol.c74
1 files changed, 64 insertions, 10 deletions
diff --git a/usr.bin/posixshmcontrol/posixshmcontrol.c b/usr.bin/posixshmcontrol/posixshmcontrol.c
index 5bf037088b41..3ebb722ae4fb 100644
--- a/usr.bin/posixshmcontrol/posixshmcontrol.c
+++ b/usr.bin/posixshmcontrol/posixshmcontrol.c
@@ -30,8 +30,10 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/filio.h>
#include <sys/mman.h>
#include <sys/stat.h>
+#include <sys/syscall.h>
#include <sys/sysctl.h>
#include <sys/user.h>
#include <err.h>
@@ -50,7 +52,7 @@ usage(void)
{
fprintf(stderr, "Usage:\n"
- "posixshmcontrol create [-m <mode>] <path> ...\n"
+ "posixshmcontrol create [-m <mode>] [-l <largepage>] <path> ...\n"
"posixshmcontrol rm <path> ...\n"
"posixshmcontrol ls [-h] [-n]\n"
"posixshmcontrol dump <path> ...\n"
@@ -59,14 +61,23 @@ usage(void)
}
static int
-create_one_shm(const char *path, long mode)
+create_one_shm(const char *path, long mode, int idx)
{
int fd;
- fd = shm_open(path, O_RDWR | O_CREAT, mode);
- if (fd == -1) {
- warn("create %s", path);
- return (1);
+ if (idx == -1) {
+ fd = shm_open(path, O_RDWR | O_CREAT, mode);
+ if (fd == -1) {
+ warn("create %s", path);
+ 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);
return (0);
@@ -76,20 +87,60 @@ static int
create_shm(int argc, char **argv)
{
char *end;
+ size_t *pagesizes;
long mode;
- int c, i, ret, ret1;
+ uint64_t pgsz;
+ int c, i, idx, pn, ret, ret1;
+ bool printed;
mode = 0600;
- while ((c = getopt(argc, argv, "m:")) != -1) {
+ idx = -1;
+ while ((c = getopt(argc, argv, "l:m:")) != -1) {
switch (c) {
case 'm':
errno = 0;
mode = strtol(optarg, &end, 0);
if (mode == 0 && errno != 0)
- err(1, "mode:");
+ err(1, "mode");
if (*end != '\0')
errx(1, "non-integer mode");
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 '?':
default:
usage();
@@ -101,7 +152,7 @@ create_shm(int argc, char **argv)
argv += optind;
ret = 0;
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)
ret = ret1;
}
@@ -349,6 +400,9 @@ stat_one_shm(const char *path, bool hsize, bool uname)
(long)st.st_ctim.tv_nsec);
printf("birth\t%ld.%09ld\n", (long)st.st_birthtim.tv_sec,
(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);
return (ret);