public inbox for ltp@lists.linux.it
 help / color / mirror / Atom feed
From: Cyril Hrubis <chrubis@suse.cz>
To: Avinesh Kumar <akumar@suse.de>
Cc: ltp@lists.linux.it
Subject: Re: [LTP] [PATCH] syscalls/mmap21: Add new test for mmap's ENOMEM case
Date: Thu, 31 Aug 2023 14:42:53 +0200	[thread overview]
Message-ID: <ZPCKzdDjSKzFayv_@yuki> (raw)
In-Reply-To: <20230831112629.21510-1-akumar@suse.de>

Hi!
> To be more precise in this test and checking for ENOMEM on exact mapping
> when limit is crossed, I could only think of counting the existing
> mappings from /proc/$pid/maps and counting the remaining possible
> mappings. Is there any better approach if we want to test this for exact
> case?

If you want to check that we managed to create exactly the amount of
mappings in this limit, this would be a sensible way to do that.

However beware that this also depends on the overcommit settings. If
kernel is not set to overcommit and if the size of the memory needed to
cross the maximal number of mappings would exceed available memory you
would get ENOMEM before you manage to hit the limit. With overcommit
enabled you can create mappings as long as the kernel has enough memory
to hold the vma structures.

At my system the limit is set to 65530 which on 4k page size would
consume around 300MB, which does not seem to be much, but may still fail
on small embedded boards with disabled overcommit. So either we try to
set the limit to a lower value for the duration of the test, or allow
the mmap() to fail sooner if we find that available memory is close to
or smaller than number of mappings multiplied by page size.

> Signed-off-by: Avinesh Kumar <akumar@suse.de>
> ---
>  testcases/kernel/syscalls/mmap/mmap21.c | 70 +++++++++++++++++++++++++
>  1 file changed, 70 insertions(+)
>  create mode 100644 testcases/kernel/syscalls/mmap/mmap21.c
> 
> diff --git a/testcases/kernel/syscalls/mmap/mmap21.c b/testcases/kernel/syscalls/mmap/mmap21.c
> new file mode 100644
> index 000000000..76002edb3
> --- /dev/null
> +++ b/testcases/kernel/syscalls/mmap/mmap21.c
> @@ -0,0 +1,70 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2023 SUSE LLC Avinesh Kumar <avinesh.kumar@suse.com>
> + */
> +
> +/*\
> + * [Description]
> + *
> + * Verify that, mmap(2) fails with errno ENOMEM when process's
> + * maximum number of mappings would have been exceeded.
> + */
> +
> +#include <stdio.h>
             ^
I do not think that this is needed, or is ti?

> +#include "tst_test.h"
> +
> +#define TEMPFILE "mmapfile"
> +static int fd;
> +static size_t page_sz;
> +static int max_map;
> +
> +static void setup(void)
> +{
> +	page_sz = getpagesize();
> +
> +	fd = SAFE_OPEN(TEMPFILE, O_RDWR | O_CREAT, 0666);

I guess that we can simplify the test by mapping anonymous memory and
get rid of the needs_tmpdir and file creation.

> +	SAFE_FILE_SCANF("/proc/sys/vm/max_map_count", "%d   ", &max_map);
> +	tst_res(TINFO, "max_map_count: %d", max_map);
> +}
> +
> +static void run(void)
> +{
> +	int i;
> +	char *addr[max_map];
> +
> +	for (i = 0; i < max_map; i++) {
> +		TESTPTR(mmap(0, page_sz, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fd, 0));
                             ^
			     Again since this is an address, it is better to be NULL.

> +		if (TST_RET_PTR != MAP_FAILED) {
> +			addr[i] = TST_RET_PTR;
> +		} else {
> +			if (TST_ERR == ENOMEM) {
> +				tst_res(TINFO, "New successful mappings before exhausting the limit: %d", i);
> +				tst_res(TPASS, "mmap() failed with ENOMEM");
> +			} else {
> +				tst_res(TINFO, "New successful mappings before mmap() failed: %d", i);
> +				tst_res(TFAIL | TERRNO, "mmap() failed with unexpected errno");
> +			}
> +			break;
> +		}
> +	}
> +
> +	if (i == max_map)
> +		tst_res(TFAIL, "mmap() crossed max_map_count limit, no of new mmapings: %d", i);
> +
> +	while (--i >= 0)
> +		SAFE_MUNMAP(addr[i], page_sz);
> +}
> +
> +static void cleanup(void)
> +{
> +	if (fd > 0)
> +		SAFE_CLOSE(fd);
> +}
> +
> +static struct tst_test test = {
> +	.setup = setup,
> +	.cleanup = cleanup,
> +	.test_all = run,
> +	.needs_tmpdir = 1
> +};
> -- 
> 2.41.0
> 
> 
> -- 
> Mailing list info: https://lists.linux.it/listinfo/ltp

-- 
Cyril Hrubis
chrubis@suse.cz

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

  reply	other threads:[~2023-08-31 12:42 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-31 11:19 [LTP] [PATCH] syscalls/mmap21: Add new test for mmap's ENOMEM case Avinesh Kumar
2023-08-31 12:42 ` Cyril Hrubis [this message]
2023-09-08  9:45   ` Richard Palethorpe

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZPCKzdDjSKzFayv_@yuki \
    --to=chrubis@suse.cz \
    --cc=akumar@suse.de \
    --cc=ltp@lists.linux.it \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox