> +static int thp_shmem_control(bool do_set)
> +{
> +     static char thp_shmem_control_str[PAGE_SIZE];
> +
> +     int fd;
> +     size_t len;
> +     ssize_t count;
> +     char *control;
> +     char control_buf[PAGE_SIZE];
> +     int ret = EXIT_SUCCESS;
> +     static const char *delim = "[]";
> +     static const char *advise = "advise";
> +
> +     fd = open("/sys/kernel/mm/transparent_hugepage/shmem_enabled", O_RDWR);
> +     if (fd < 0) {
> +             ksft_perror("failed to open thp control");
> +             return EXIT_FAILURE;
> +     }
> +
> +     if (do_set) {
> +             if (strlen(thp_shmem_control_str) != 0) {
> +                     ksft_print_msg("thp control has already been set\n");
> +                     goto out;
> +
> +             }
> +             count = read(fd, control_buf, PAGE_SIZE - 1);
> +             if (count < 0) {
> +                     ksft_perror("failed to read thp control");
> +                     ret = EXIT_FAILURE;
> +                     goto out;
> +             };
> +             control_buf[count] = '\0';
> +
> +             control = strtok(control_buf, delim);
> +             if (control_buf[0] != '[')

After we call strtok on control_buf, we should not use control_buf anymore as 
strtok man suggests that strtok can modify the first argument, and we can see 
there something which was not there originally.

> +                     control = strtok(NULL, delim);
> +
> +             len = strlen(advise);
> +             if (write(fd, advise, len) != len) {
> +                     ksft_print_msg("failed to write thp control");
> +                     ret = EXIT_FAILURE;
> +                     goto out;
> +             }
> +             strncpy(thp_shmem_control_str, control, PAGE_SIZE - 1);
> +     } else {
...
> +static void verify_stats(struct test_context *ctx, const char *cgroup,
> +                      const char *stat)
> +{
> +     int parsed_nodes;
> +     int n;
> +     size_t per_node;
> +     size_t node_stat[NUMA_NUM_NODES];
> +     int ret = EXIT_SUCCESS;
> +     int retries_left = 100; /* 10s */
> +
> +     EXPAND_CTX(ctx);
> +retry:
> +     retries_left--;
> +     memset(node_stat, 0, node_count * sizeof(size_t));
> +
> +     parsed_nodes = parse_memory_numa_stat(ctx, cgroup, stat, node_stat);
> +     ASSERT_EQ(node_count, parsed_nodes)
> +             ksft_print_msg("failed to parse numa stat\n");
> +
> +     /* values_close() does not work well with 0 */
> +     if (node_stat[src_node] > file_size / 100 * 15) {
> +             if (retries_left > 0) {
> +                     usleep(100000); /* 100ms */
> +                     goto retry;
> +             }
> +             ksft_print_msg("too much memory left on node%i\n",
> +                             src_node);
> +             ret = EXIT_FAILURE;
> +             goto dump_stat;
> +     }
> +
> +     per_node = file_size / dst_count;
> +     for (n = 0; n < numa_max_possible_node(); n++) {
> +             if (numa_bitmask_isbitset(dst_mask, n) &&
> +             !values_close(node_stat[n], per_node, 15)) {
> +                     if (retries_left > 0) {
> +                             usleep(100000); /* 100ms */
> +                             goto retry;
> +                     }
> +                     ksft_print_msg("not enough memory moved to node%i\n", 
> n);
> +                     ret = EXIT_FAILURE;
> +             }
> +     }
> +
> +dump_stat:
> +     if (ret != EXIT_SUCCESS) {
> +             ksft_print_msg("size=%li\n", file_size);

%zu for size_t

> +             dump_memory_numa_stat(node_stat);
> +     }
> +
> +     ASSERT_EQ(EXIT_SUCCESS, ret);
> +}
> +

-- 
Best regards, Pavel Tikhomirov
Senior Software Developer, Virtuozzo.

_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to