From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.9 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4B456C433DF for ; Tue, 7 Jul 2020 14:47:09 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id F22C520786 for ; Tue, 7 Jul 2020 14:47:08 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=amazon.com header.i=@amazon.com header.b="s9T9m4Ep" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org F22C520786 Authentication-Results: mail.kernel.org; dmarc=fail (p=quarantine dis=none) header.from=amazon.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id A06FF8D0011; Tue, 7 Jul 2020 10:47:08 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 9B66B8D0007; Tue, 7 Jul 2020 10:47:08 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 8A5A78D0011; Tue, 7 Jul 2020 10:47:08 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0023.hostedemail.com [216.40.44.23]) by kanga.kvack.org (Postfix) with ESMTP id 73A6A8D0007 for ; Tue, 7 Jul 2020 10:47:08 -0400 (EDT) Received: from smtpin21.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay02.hostedemail.com (Postfix) with ESMTP id 1756C33C4 for ; Tue, 7 Jul 2020 14:47:08 +0000 (UTC) X-FDA: 77011557336.21.beds51_09106ae26eb5 Received: from filter.hostedemail.com (10.5.16.251.rfc1918.com [10.5.16.251]) by smtpin21.hostedemail.com (Postfix) with ESMTP id DDF5D180442C2 for ; Tue, 7 Jul 2020 14:47:07 +0000 (UTC) X-HE-Tag: beds51_09106ae26eb5 X-Filterd-Recvd-Size: 8887 Received: from smtp-fw-9101.amazon.com (smtp-fw-9101.amazon.com [207.171.184.25]) by imf13.hostedemail.com (Postfix) with ESMTP for ; Tue, 7 Jul 2020 14:47:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.com; i=@amazon.com; q=dns/txt; s=amazon201209; t=1594133228; x=1625669228; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=TdYn9I/dab2QRRAdgNTXi0s6WRxFPOrf2d2Y2+9DpV0=; b=s9T9m4EpmBTMV6HpClAUcXgTz07Na9jiUajv99cddW2LwvlG5k5LKJbw O5iOIpdzV2pa6MHsa7NBsqWh2RKU0uCdYajrnRh+xr0JMVH8ThMQDLRi8 Yxz0Fc/TZpvDbovCwbcG9yMJ27rA7q4nqwLWk/qrzEbKUB64R4Zf0GxV3 Q=; IronPort-SDR: 8ISh1n4xJWw6dp4nSl0ozFXxV7tkFl64SD+MQTm+d9hA1LT5Y7jP4I4QI2g70NhYKvz+rYXYgn mmM38HhIjl/A== X-IronPort-AV: E=Sophos;i="5.75,324,1589241600"; d="scan'208";a="49756041" Received: from sea32-co-svc-lb4-vlan3.sea.corp.amazon.com (HELO email-inbound-relay-2a-c5104f52.us-west-2.amazon.com) ([10.47.23.38]) by smtp-border-fw-out-9101.sea19.amazon.com with ESMTP; 07 Jul 2020 14:46:56 +0000 Received: from EX13MTAUEA002.ant.amazon.com (pdx4-ws-svc-p6-lb7-vlan3.pdx.amazon.com [10.170.41.166]) by email-inbound-relay-2a-c5104f52.us-west-2.amazon.com (Postfix) with ESMTPS id 65A2CA2038; Tue, 7 Jul 2020 14:46:53 +0000 (UTC) Received: from EX13D31EUA004.ant.amazon.com (10.43.165.161) by EX13MTAUEA002.ant.amazon.com (10.43.61.77) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Tue, 7 Jul 2020 14:46:52 +0000 Received: from u886c93fd17d25d.ant.amazon.com (10.43.161.214) by EX13D31EUA004.ant.amazon.com (10.43.165.161) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Tue, 7 Jul 2020 14:46:33 +0000 From: SeongJae Park To: CC: SeongJae Park , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , Subject: [RFC v5 01/11] mm/damon/debugfs: Allow users to set initial monitoring target regions Date: Tue, 7 Jul 2020 16:45:30 +0200 Message-ID: <20200707144540.21216-2-sjpark@amazon.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200707144540.21216-1-sjpark@amazon.com> References: <20200707144540.21216-1-sjpark@amazon.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.43.161.214] X-ClientProxiedBy: EX13D35UWC001.ant.amazon.com (10.43.162.197) To EX13D31EUA004.ant.amazon.com (10.43.165.161) X-Rspamd-Queue-Id: DDF5D180442C2 X-Spamd-Result: default: False [0.00 / 100.00] X-Rspamd-Server: rspam01 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: From: SeongJae Park Some users would want to monitor only a part of the entire virtual memory address space. The '->init_target_regions' callback is therefore provided, but only programming interface can use it. For the reason, this commit introduces a new debugfs file, 'init_region'. Users can specify which initial monitoring target address regions they want by writing special input to the file. The input should describe each region in each line in below form: This commit also makes the default '->init_target_regions' callback, 'kdamon_init_vm_regions()' to do nothing if the user has set the initial target regions already. Note that the regions will be updated to cover entire memory mapped regions after 'regions update interval'. If you want the regions to not be updated after the initial setting, you could set the interval as a very long time, say, a few decades. Signed-off-by: SeongJae Park --- mm/damon.c | 156 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 152 insertions(+), 4 deletions(-) diff --git a/mm/damon.c b/mm/damon.c index 937b6bccb7b8..3aecdef4c841 100644 --- a/mm/damon.c +++ b/mm/damon.c @@ -1800,6 +1800,147 @@ static ssize_t debugfs_record_write(struct file *file, return ret; } +static ssize_t sprint_init_regions(struct damon_ctx *c, char *buf, ssize_t len) +{ + struct damon_task *t; + struct damon_region *r; + int written = 0; + int rc; + + damon_for_each_task(t, c) { + damon_for_each_region(r, t) { + rc = snprintf(&buf[written], len - written, + "%d %lu %lu\n", + t->pid, r->ar.start, r->ar.end); + if (!rc) + return -ENOMEM; + written += rc; + } + } + return written; +} + +static ssize_t debugfs_init_regions_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + struct damon_ctx *ctx = &damon_user_ctx; + char *kbuf; + ssize_t len; + + kbuf = kmalloc(count, GFP_KERNEL); + if (!kbuf) + return -ENOMEM; + + mutex_lock(&ctx->kdamond_lock); + if (ctx->kdamond) { + mutex_unlock(&ctx->kdamond_lock); + return -EBUSY; + } + + len = sprint_init_regions(ctx, kbuf, count); + mutex_unlock(&ctx->kdamond_lock); + if (len < 0) + goto out; + len = simple_read_from_buffer(buf, count, ppos, kbuf, len); + +out: + kfree(kbuf); + return len; +} + +static int add_init_region(struct damon_ctx *c, + int pid, struct damon_addr_range *ar) +{ + struct damon_task *t; + struct damon_region *r, *prev; + int rc = -EINVAL; + + if (ar->start >= ar->end) + return -EINVAL; + + damon_for_each_task(t, c) { + if (t->pid == pid) { + r = damon_new_region(ar->start, ar->end); + if (!r) + return -ENOMEM; + damon_add_region(r, t); + if (nr_damon_regions(t) > 1) { + prev = damon_prev_region(r); + if (prev->ar.end > r->ar.start) { + damon_destroy_region(r); + return -EINVAL; + } + } + rc = 0; + } + } + return rc; +} + +static int set_init_regions(struct damon_ctx *c, const char *str, ssize_t len) +{ + struct damon_task *t; + struct damon_region *r, *next; + int pos = 0, parsed, ret; + int pid; + struct damon_addr_range ar; + int err; + + damon_for_each_task(t, c) { + damon_for_each_region_safe(r, next, t) + damon_destroy_region(r); + } + + while (pos < len) { + ret = sscanf(&str[pos], "%d %lu %lu%n", + &pid, &ar.start, &ar.end, &parsed); + if (ret != 3) + break; + err = add_init_region(c, pid, &ar); + if (err) + goto fail; + pos += parsed; + } + + return 0; + +fail: + damon_for_each_task(t, c) { + damon_for_each_region_safe(r, next, t) + damon_destroy_region(r); + } + return err; +} + +static ssize_t debugfs_init_regions_write(struct file *file, + const char __user *buf, size_t count, + loff_t *ppos) +{ + struct damon_ctx *ctx = &damon_user_ctx; + char *kbuf; + ssize_t ret = count; + int err; + + kbuf = user_input_str(buf, count, ppos); + if (IS_ERR(kbuf)) + return PTR_ERR(kbuf); + + mutex_lock(&ctx->kdamond_lock); + if (ctx->kdamond) { + ret = -EBUSY; + goto unlock_out; + } + + err = set_init_regions(ctx, kbuf, ret); + if (err) + ret = err; + +unlock_out: + mutex_unlock(&ctx->kdamond_lock); + kfree(kbuf); + return ret; +} + static ssize_t debugfs_attrs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { @@ -1876,6 +2017,12 @@ static const struct file_operations record_fops = { .write = debugfs_record_write, }; +static const struct file_operations init_regions_fops = { + .owner = THIS_MODULE, + .read = debugfs_init_regions_read, + .write = debugfs_init_regions_write, +}; + static const struct file_operations attrs_fops = { .owner = THIS_MODULE, .read = debugfs_attrs_read, @@ -1886,10 +2033,11 @@ static struct dentry *debugfs_root; static int __init damon_debugfs_init(void) { - const char * const file_names[] = {"attrs", "record", "schemes", - "pids", "monitor_on"}; - const struct file_operations *fops[] = {&attrs_fops, &record_fops, - &schemes_fops, &pids_fops, &monitor_on_fops}; + const char * const file_names[] = {"attrs", "init_regions", "record", + "schemes", "pids", "monitor_on"}; + const struct file_operations *fops[] = {&attrs_fops, + &init_regions_fops, &record_fops, &schemes_fops, &pids_fops, + &monitor_on_fops}; int i; debugfs_root = debugfs_create_dir("damon", NULL); -- 2.17.1