From adce35320f00f09f4c1e5f0303a771ec205a20fd Mon Sep 17 00:00:00 2001 From: kib Date: Wed, 9 Sep 2020 22:22:02 +0000 Subject: [PATCH] Add posixshmcontrol(1) support for largepage shm objects. Create op with -l 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 --- usr.bin/posixshmcontrol/posixshmcontrol.c | 74 ++++++++++++++++++++--- 1 file 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 +#include #include #include +#include #include #include #include @@ -50,7 +52,7 @@ usage(void) { fprintf(stderr, "Usage:\n" - "posixshmcontrol create [-m ] ...\n" + "posixshmcontrol create [-m ] [-l ] ...\n" "posixshmcontrol rm ...\n" "posixshmcontrol ls [-h] [-n]\n" "posixshmcontrol dump ...\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);