Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp1683030imm; Sat, 29 Sep 2018 01:45:23 -0700 (PDT) X-Google-Smtp-Source: ACcGV62liwdSLgo5YWdbniY6kwgrds+zw/Qmrs/uefReVR3eGakU/WCYeLPhLrAMZkuOkqC0Qxzc X-Received: by 2002:a63:4d5b:: with SMTP id n27-v6mr2083375pgl.270.1538210723276; Sat, 29 Sep 2018 01:45:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1538210723; cv=none; d=google.com; s=arc-20160816; b=e0jI8cuCR6VLtD0KF/rlzj7jHW+PqzwMt/SbU3FR/kJ305v3JxSU1AFaqOP2r2u7x4 fxz7uy33//CJXodr9p1mVsW29CcwDXY86oqyI/TrPYIbQYEHFHYGSB93fSGzO4ReqimZ k0V7yegBMDdMmeMioGNEgfigAZnLcVXwJn58yhnTw4dfZ0VxWeRk7LoIxLxLRqjTvLxq dwHVr+t66FBqwKYtkWwg/RdQG9cuWdHHSHsLuReO6Ilay1SAXecBqOJNWevWKgrRH7+h 0Tbmkfhr3ou+c7WPXz1U0MzVDekIEa7luHBn82lNnUOQQNyg6em5oK0a0b2HQAkSIqeG ojPw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=ye/75/THLV4vdRy1JAIrltokdN0e0k9yoEs0CUVH5OA=; b=evQWvfuL67oS2FCj4sP7oZl/32VglwkSDia/qJwa99FJmZ5tcKTrQ2u4jnx/rf9OZu GkPV66Q7hg1WQqVEsq/AowkcoPRHsj5CJfqjiM+ahAuVBlr846Cl1Jt7wIzoAQIzvI8n NTzEyKX1ccZOcAYBgvbReOnQEVI/cFz/dCT8JbbPum2jkcRnhLZmcx5v7cahFoAIuoGm n+Q6SzZVUNzLV2wztfZfSWNTouTKBbgOQ5lBaKPYVdbdE9GxOzyGmsOk74hbkV7Hc5h3 75bzcX38TpsbFNKBhjTk6o3x6qoqoJT/bReoXG+caMwxB4XfTBd38ZtSOa3f+Xt3BKUR siSw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id t1-v6si6992121pfb.208.2018.09.29.01.45.08; Sat, 29 Sep 2018 01:45:23 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727854AbeI2PLF (ORCPT + 99 others); Sat, 29 Sep 2018 11:11:05 -0400 Received: from mx1.redhat.com ([209.132.183.28]:43454 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727823AbeI2PLF (ORCPT ); Sat, 29 Sep 2018 11:11:05 -0400 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 4C8398762B; Sat, 29 Sep 2018 08:43:29 +0000 (UTC) Received: from xz-x1.nay.redhat.com (dhcp-14-128.nay.redhat.com [10.66.14.128]) by smtp.corp.redhat.com (Postfix) with ESMTP id F0C6A106A790; Sat, 29 Sep 2018 08:43:24 +0000 (UTC) From: Peter Xu To: linux-kernel@vger.kernel.org Cc: Shuah Khan , Jerome Glisse , Mike Rapoport , Mike Kravetz , peterx@redhat.com, linux-mm@kvack.org, Zi Yan , "Kirill A . Shutemov" , linux-kselftest@vger.kernel.org, Shaohua Li , Andrea Arcangeli , "Dr . David Alan Gilbert" , Andrew Morton Subject: [PATCH 2/3] userfaultfd: selftest: generalize read and poll Date: Sat, 29 Sep 2018 16:43:10 +0800 Message-Id: <20180929084311.15600-3-peterx@redhat.com> In-Reply-To: <20180929084311.15600-1-peterx@redhat.com> References: <20180929084311.15600-1-peterx@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Sat, 29 Sep 2018 08:43:29 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org We do very similar things in read and poll modes, but we're copying the codes around. Share the codes properly on reading the message and handling the page fault to make the code cleaner. Meanwhile this solves previous mismatch of behaviors between the two modes on that the old code: - did not check EAGAIN case in read() mode - ignored BOUNCE_VERIFY check in read() mode Signed-off-by: Peter Xu --- tools/testing/selftests/vm/userfaultfd.c | 76 +++++++++++++----------- 1 file changed, 42 insertions(+), 34 deletions(-) diff --git a/tools/testing/selftests/vm/userfaultfd.c b/tools/testing/selftests/vm/userfaultfd.c index 2a84adaf8cf8..f79706f13ce7 100644 --- a/tools/testing/selftests/vm/userfaultfd.c +++ b/tools/testing/selftests/vm/userfaultfd.c @@ -449,6 +449,42 @@ static int copy_page(int ufd, unsigned long offset) return __copy_page(ufd, offset, false); } +static int uffd_read_msg(int ufd, struct uffd_msg *msg) +{ + int ret = read(uffd, msg, sizeof(*msg)); + + if (ret != sizeof(*msg)) { + if (ret < 0) + if (errno == EAGAIN) + return 1; + else + perror("blocking read error"), exit(1); + else + fprintf(stderr, "short read\n"), exit(1); + } + + return 0; +} + +/* Return 1 if page fault handled by us; otherwise 0 */ +static int uffd_handle_page_fault(struct uffd_msg *msg) +{ + unsigned long offset; + + if (msg->event != UFFD_EVENT_PAGEFAULT) + fprintf(stderr, "unexpected msg event %u\n", + msg->event), exit(1); + + if (bounces & BOUNCE_VERIFY && + msg->arg.pagefault.flags & UFFD_PAGEFAULT_FLAG_WRITE) + fprintf(stderr, "unexpected write fault\n"), exit(1); + + offset = (char *)(unsigned long)msg->arg.pagefault.address - area_dst; + offset &= ~(page_size-1); + + return copy_page(uffd, offset); +} + static void *uffd_poll_thread(void *arg) { unsigned long cpu = (unsigned long) arg; @@ -456,7 +492,6 @@ static void *uffd_poll_thread(void *arg) struct uffd_msg msg; struct uffdio_register uffd_reg; int ret; - unsigned long offset; char tmp_chr; unsigned long userfaults = 0; @@ -480,25 +515,15 @@ static void *uffd_poll_thread(void *arg) if (!(pollfd[0].revents & POLLIN)) fprintf(stderr, "pollfd[0].revents %d\n", pollfd[0].revents), exit(1); - ret = read(uffd, &msg, sizeof(msg)); - if (ret < 0) { - if (errno == EAGAIN) - continue; - perror("nonblocking read error"), exit(1); - } + if (uffd_read_msg(uffd, &msg)) + continue; switch (msg.event) { default: fprintf(stderr, "unexpected msg event %u\n", msg.event), exit(1); break; case UFFD_EVENT_PAGEFAULT: - if (msg.arg.pagefault.flags & UFFD_PAGEFAULT_FLAG_WRITE) - fprintf(stderr, "unexpected write fault\n"), exit(1); - offset = (char *)(unsigned long)msg.arg.pagefault.address - - area_dst; - offset &= ~(page_size-1); - if (copy_page(uffd, offset)) - userfaults++; + userfaults += uffd_handle_page_fault(&msg); break; case UFFD_EVENT_FORK: close(uffd); @@ -526,8 +551,6 @@ static void *uffd_read_thread(void *arg) { unsigned long *this_cpu_userfaults; struct uffd_msg msg; - unsigned long offset; - int ret; this_cpu_userfaults = (unsigned long *) arg; *this_cpu_userfaults = 0; @@ -536,24 +559,9 @@ static void *uffd_read_thread(void *arg) /* from here cancellation is ok */ for (;;) { - ret = read(uffd, &msg, sizeof(msg)); - if (ret != sizeof(msg)) { - if (ret < 0) - perror("blocking read error"), exit(1); - else - fprintf(stderr, "short read\n"), exit(1); - } - if (msg.event != UFFD_EVENT_PAGEFAULT) - fprintf(stderr, "unexpected msg event %u\n", - msg.event), exit(1); - if (bounces & BOUNCE_VERIFY && - msg.arg.pagefault.flags & UFFD_PAGEFAULT_FLAG_WRITE) - fprintf(stderr, "unexpected write fault\n"), exit(1); - offset = (char *)(unsigned long)msg.arg.pagefault.address - - area_dst; - offset &= ~(page_size-1); - if (copy_page(uffd, offset)) - (*this_cpu_userfaults)++; + if (uffd_read_msg(uffd, &msg)) + continue; + (*this_cpu_userfaults) += uffd_handle_page_fault(&msg); } return (void *)NULL; } -- 2.17.1