From patchwork Wed Aug 1 23:36:36 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Safonov X-Patchwork-Id: 10553121 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EABBB15E9 for ; Wed, 1 Aug 2018 23:36:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DA8B526247 for ; Wed, 1 Aug 2018 23:36:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CC9E129C05; Wed, 1 Aug 2018 23:36:41 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 33CA126247 for ; Wed, 1 Aug 2018 23:36:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730841AbeHBBYy (ORCPT ); Wed, 1 Aug 2018 21:24:54 -0400 Received: from mail-ed1-f66.google.com ([209.85.208.66]:38440 "EHLO mail-ed1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729409AbeHBBYy (ORCPT ); Wed, 1 Aug 2018 21:24:54 -0400 Received: by mail-ed1-f66.google.com with SMTP id t2-v6so261873edr.5 for ; Wed, 01 Aug 2018 16:36:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=arista.com; s=googlenew; h=from:to:cc:subject:date:message-id; bh=zysA6SIB37bEfWOqteBNHnQc4SaQRKzqRTTc8rlBub4=; b=F/UU6SelhSD3DQnAvbDG797+4q78LsRj5d8HDNebn/7y0KofRgltMGPnG0Hwe1ddi3 gbNooRArZQAozXv33PVNvxEGic+muSc80w2waYrgTWPeqMbruKWLJfcftAATHyzVRYHO HDuMXp6Hqllgrj+LJrLeP3VH088vYTe3gpZG+oGfpDjE1eZabSk1fIBZyZYInMMxjfzL TKCtpi/WHcYQT4XITwky6zbD9cmoG9Ga6YbuipmofzQRJlJtIodeOY7AsoWnSol3S+lk gF2esoZtIa0msVTwHiAnIod0P5EaYQ7TOUHlqZNeAehlJOpnnRBrh11hJT6TW2r3aTdY qUqA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=zysA6SIB37bEfWOqteBNHnQc4SaQRKzqRTTc8rlBub4=; b=X6zJpiRga03i+eIkGqxi5UlsXPTRdM9SKIyhghvzEHjUKqdgYbsZfDmBFDTM6UBOE4 9vwfZUallEQq0euJ0ONro47LPEfaElUh8NdwCVgVnzN1byxXL35REuLd3nEo0cHo94VX k+KouTK7oPIijxnJsTqIYJ+qcMRarRU3lyLbfR3nssUJtLJNynCgsaG+whoDV/EoBGyr C2H2i0cae6e4Ig6aZOHpfWhTf0a7JLbvxDZgb51Tm9XyBCZ+iwg3CAMd4JqbphyjXoel Qbb6vSKdCs8W29U8n89VcPJfgu1Ib3TlIIzh7XuBtkMXwYJ3emupu8EXlKf538gkI3/B 9sMw== X-Gm-Message-State: AOUpUlGe8EOZKaQY6nzVsqjKG1wtoXtyfPJ+Q9Y7Hui7Xa4Q3EO+htY8 Afgkl+HWH1jW8BeESOvgqKs83gJK+D8= X-Google-Smtp-Source: AAOMgpcDEBsTAsdoLojtjIQO0qOFVAQCxUpQSjqQnQjsL7UlT6xDDDmDnb3xScmzv6VA4VwVwCvLHQ== X-Received: by 2002:aa7:d859:: with SMTP id f25-v6mr728243eds.157.1533166598137; Wed, 01 Aug 2018 16:36:38 -0700 (PDT) Received: from dhcp.ire.aristanetworks.com ([217.173.96.166]) by smtp.gmail.com with ESMTPSA id b44-v6sm582086edd.93.2018.08.01.16.36.36 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 01 Aug 2018 16:36:37 -0700 (PDT) From: Dmitry Safonov To: linux-kernel@vger.kernel.org Cc: Dmitry Safonov , Andrew Morton , Dmitry Safonov <0x7f454c46@gmail.com>, Hua Zhong , Shuah Khan , Stuart Ritchie , linux-kselftest@vger.kernel.org Subject: [PATCH] mm/selftest: Add MAP_POPULATE test Date: Thu, 2 Aug 2018 00:36:36 +0100 Message-Id: <20180801233636.29354-1-dima@arista.com> X-Mailer: git-send-email 2.13.6 Sender: linux-kselftest-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP As many other projects, we use some shmalloc allocator. At some point we need to make a part of allocated pages back private to process. And it should be populated straight away. Check that (MAP_PRIVATE | MAP_POPULATE) actually copies the private page. Cc: Andrew Morton Cc: Dmitry Safonov <0x7f454c46@gmail.com> Cc: Hua Zhong Cc: Shuah Khan Cc: Stuart Ritchie Cc: linux-kselftest@vger.kernel.org Signed-off-by: Dmitry Safonov --- tools/testing/selftests/vm/.gitignore | 1 + tools/testing/selftests/vm/Makefile | 1 + tools/testing/selftests/vm/map_populate.c | 113 ++++++++++++++++++++++++++++++ tools/testing/selftests/vm/run_vmtests | 11 +++ 4 files changed, 126 insertions(+) create mode 100644 tools/testing/selftests/vm/map_populate.c diff --git a/tools/testing/selftests/vm/.gitignore b/tools/testing/selftests/vm/.gitignore index 342c7bc9dc8c..af5ff83f6d7f 100644 --- a/tools/testing/selftests/vm/.gitignore +++ b/tools/testing/selftests/vm/.gitignore @@ -1,6 +1,7 @@ hugepage-mmap hugepage-shm map_hugetlb +map_populate thuge-gen compaction_test mlock2-tests diff --git a/tools/testing/selftests/vm/Makefile b/tools/testing/selftests/vm/Makefile index fdefa2295ddc..9881876d2aa0 100644 --- a/tools/testing/selftests/vm/Makefile +++ b/tools/testing/selftests/vm/Makefile @@ -12,6 +12,7 @@ TEST_GEN_FILES += gup_benchmark TEST_GEN_FILES += hugepage-mmap TEST_GEN_FILES += hugepage-shm TEST_GEN_FILES += map_hugetlb +TEST_GEN_FILES += map_populate TEST_GEN_FILES += mlock-random-test TEST_GEN_FILES += mlock2-tests TEST_GEN_FILES += on-fault-limit diff --git a/tools/testing/selftests/vm/map_populate.c b/tools/testing/selftests/vm/map_populate.c new file mode 100644 index 000000000000..df3eacc8eecb --- /dev/null +++ b/tools/testing/selftests/vm/map_populate.c @@ -0,0 +1,113 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018 Dmitry Safonov, Arista Networks + * + * MAP_POPULATE | MAP_PRIVATE should COW VMA pages. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef MMAP_SZ +#define MMAP_SZ 4096 +#endif + +#define BUG_ON(condition, description) \ + do { \ + if (condition) { \ + fprintf(stderr, "[FAIL]\t%s:%d\t%s:%s\n", __func__, \ + __LINE__, (description), strerror(errno)); \ + exit(1); \ + } \ + } while (0) + +static int parent_f(int sock, unsigned long *smap, int child) +{ + int status, ret; + + ret = read(sock, &status, sizeof(int)); + BUG_ON(ret <= 0, "read(sock)"); + + *smap = 0x22222BAD; + ret = msync(smap, MMAP_SZ, MS_SYNC); + BUG_ON(ret, "msync()"); + + ret = write(sock, &status, sizeof(int)); + BUG_ON(ret <= 0, "write(sock)"); + + waitpid(child, &status, 0); + BUG_ON(!WIFEXITED(status), "child hasn't suicide by own will"); + + return WEXITSTATUS(status); +} + +static int child_f(int sock, unsigned long *smap, int fd) +{ + int ret, buf = 0; + + smap = mmap(0, MMAP_SZ, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_POPULATE, fd, 0); + BUG_ON(smap == MAP_FAILED, "mmap()"); + + BUG_ON(*smap != 0xdeadbabe, "MAP_PRIVATE | MAP_POPULATE changed file"); + + ret = write(sock, &buf, sizeof(int)); + BUG_ON(ret <= 0, "write(sock)"); + + ret = read(sock, &buf, sizeof(int)); + BUG_ON(ret <= 0, "read(sock)"); + + BUG_ON(*smap == 0x22222BAD, "MAP_POPULATE didn't COW private page"); + BUG_ON(*smap != 0xdeadbabe, "mapping was corrupted"); + + return 0; +} + +int main(int argc, char **argv) +{ + int sock[2], child, ret; + FILE *ftmp; + unsigned long *smap; + + ftmp = tmpfile(); + BUG_ON(ftmp == 0, "tmpfile()"); + + ret = ftruncate(fileno(ftmp), MMAP_SZ); + BUG_ON(ret, "ftruncate()"); + + smap = mmap(0, MMAP_SZ, PROT_READ | PROT_WRITE, + MAP_SHARED, fileno(ftmp), 0); + BUG_ON(smap == MAP_FAILED, "mmap()"); + + *smap = 0xdeadbabe; + /* Probably unnecessary, but let it be. */ + ret = msync(smap, MMAP_SZ, MS_SYNC); + BUG_ON(ret, "msync()"); + + ret = socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sock); + BUG_ON(ret, "socketpair()"); + + child = fork(); + BUG_ON(child == -1, "fork()"); + + if (child) { + ret = close(sock[0]); + BUG_ON(ret, "close()"); + + return parent_f(sock[1], smap, child); + } + + ret = close(sock[1]); + BUG_ON(ret, "close()"); + + return child_f(sock[0], smap, fileno(ftmp)); +} diff --git a/tools/testing/selftests/vm/run_vmtests b/tools/testing/selftests/vm/run_vmtests index 88cbe5575f0c..584a91ae4a8f 100755 --- a/tools/testing/selftests/vm/run_vmtests +++ b/tools/testing/selftests/vm/run_vmtests @@ -168,6 +168,17 @@ else fi echo "--------------------" +echo "running map_populate" +echo "--------------------" +./map_populate +if [ $? -ne 0 ]; then + echo "[FAIL]" + exitcode=1 +else + echo "[PASS]" +fi + +echo "--------------------" echo "running mlock2-tests" echo "--------------------" ./mlock2-tests