Received: by 2002:a05:6a10:22f:0:0:0:0 with SMTP id 15csp875222pxk; Mon, 31 Aug 2020 03:49:55 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyqarmbYlyw/Z1UetFioBH2rjxweYJ/WVZafyTgor8vkOis2kXbl6sk8uUPXIrWOVvyEaKz X-Received: by 2002:a17:907:4037:: with SMTP id nk7mr548719ejb.84.1598870995739; Mon, 31 Aug 2020 03:49:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1598870995; cv=none; d=google.com; s=arc-20160816; b=mmifmTaPHP7KILX/fsCAxk8xhaHNHPP7hKX+eqgVzw+mTKAMfuUcK4mp03zNylvYXO c71FyHUrT6kyEctpc7ej4RzTye1DsYeW3BYsvaCigYIyuh16jGXSMvQ2Lv7tAkFHFOmb xMW0ZW0n2wm/s8wYJ32hnTdnEMQvqNx067u+YvpTB4hkyqVkeGoo36Fk7ddNsu7RxYG9 FsEORLzCejOxXLZznBJ7JvEGW8Pfd2bKN/gXUsmqrpT9GwZeW2S10j3r0UyUrjGDEGrO zdWiJCzy7xUR88FlbmPFQ+ihjGdfRuTHpMiyvEqkagPUIZmQZcd3IL3jo8udnrBUSu0L 5g3g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=c1UuIiNQ4tKf+PjubMku+iTkAyx0wbyj2J7tAMnPRis=; b=JctWWcrVgeURwzJjP2qQKGw1uHVmEJZwKtL/hCxfzZrew2sxRNeru/oPTqP8aMe27O +wZ9RaTRgE+P03GVMPlZ4hdMsfbn0qUWUHKraI3+hEyquJwbilTkuzefGHoIAli21eNO +AIk+tGkVTg/VfTpeDsL/hOCBUV+keKvzQS7zSF1XOrMzQb1sDHh/+d3rQYBtksbwZGY 9QtXQ76w/owuIpmOSFcnkv2O3kig2IWVNSq+pboUdiSVMOjv1fJuXQJk4EstJkifD7/k ocOP9PUDcKdZMZDFLe8NA1UDWkzcFpFDzzK2ZJcxh+WIVZBHlWp2ZRN0Yn97vQViWhFg Na/g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@amazon.com header.s=amazon201209 header.b=sei81R8C; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=amazon.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id y10si5369240edi.9.2020.08.31.03.49.33; Mon, 31 Aug 2020 03:49:55 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@amazon.com header.s=amazon201209 header.b=sei81R8C; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=amazon.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726586AbgHaKsh (ORCPT + 99 others); Mon, 31 Aug 2020 06:48:37 -0400 Received: from smtp-fw-6001.amazon.com ([52.95.48.154]:58855 "EHLO smtp-fw-6001.amazon.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726042AbgHaKsa (ORCPT ); Mon, 31 Aug 2020 06:48:30 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.com; i=@amazon.com; q=dns/txt; s=amazon201209; t=1598870909; x=1630406909; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=c1UuIiNQ4tKf+PjubMku+iTkAyx0wbyj2J7tAMnPRis=; b=sei81R8CmHVistig3+uRbPIyTkvK509bBtP1Uv+HVkgiuse1L6mlX+1V lOsGC/mENVVsNA9gDCf1LSbmKdXueCj8fA4z959v/1czO5IPjAjeTBaWS FM4bmwFg2ouZu8c2cuvaHEBG8N5S5VvtSY7d374V5ZdR8G1OqXBNVDH9B I=; X-IronPort-AV: E=Sophos;i="5.76,375,1592870400"; d="scan'208";a="52524420" Received: from iad12-co-svc-p1-lb1-vlan3.amazon.com (HELO email-inbound-relay-2c-6f38efd9.us-west-2.amazon.com) ([10.43.8.6]) by smtp-border-fw-out-6001.iad6.amazon.com with ESMTP; 31 Aug 2020 10:48:25 +0000 Received: from EX13D31EUB001.ant.amazon.com (pdx4-ws-svc-p6-lb7-vlan3.pdx.amazon.com [10.170.41.166]) by email-inbound-relay-2c-6f38efd9.us-west-2.amazon.com (Postfix) with ESMTPS id 12B5FA29EF; Mon, 31 Aug 2020 10:48:21 +0000 (UTC) Received: from u3f2cd687b01c55.ant.amazon.com (10.43.160.100) by EX13D31EUB001.ant.amazon.com (10.43.166.210) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Mon, 31 Aug 2020 10:48:03 +0000 From: SeongJae Park To: CC: SeongJae Park , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , Subject: [RFC v8 01/10] mm/damon/debugfs: Allow users to set initial monitoring target regions Date: Mon, 31 Aug 2020 12:47:21 +0200 Message-ID: <20200831104730.28970-2-sjpark@amazon.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200831104730.28970-1-sjpark@amazon.com> References: <20200831104730.28970-1-sjpark@amazon.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.43.160.100] X-ClientProxiedBy: EX13D49UWB002.ant.amazon.com (10.43.163.68) To EX13D31EUB001.ant.amazon.com (10.43.166.210) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 7e3c8c82a010..9815d22fc4de 100644 --- a/mm/damon.c +++ b/mm/damon.c @@ -2001,6 +2001,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_target *t; + struct damon_region *r; + int written = 0; + int rc; + + damon_for_each_target(t, c) { + damon_for_each_region(r, t) { + rc = snprintf(&buf[written], len - written, + "%lu %lu %lu\n", + t->id, 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, + unsigned long target_id, struct damon_addr_range *ar) +{ + struct damon_target *t; + struct damon_region *r, *prev; + int rc = -EINVAL; + + if (ar->start >= ar->end) + return -EINVAL; + + damon_for_each_target(t, c) { + if (t->id == target_id) { + 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_target *t; + struct damon_region *r, *next; + int pos = 0, parsed, ret; + unsigned long target_id; + struct damon_addr_range ar; + int err; + + damon_for_each_target(t, c) { + damon_for_each_region_safe(r, next, t) + damon_destroy_region(r); + } + + while (pos < len) { + ret = sscanf(&str[pos], "%lu %lu %lu%n", + &target_id, &ar.start, &ar.end, &parsed); + if (ret != 3) + break; + err = add_init_region(c, target_id, &ar); + if (err) + goto fail; + pos += parsed; + } + + return 0; + +fail: + damon_for_each_target(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) { @@ -2077,6 +2218,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, @@ -2087,10 +2234,11 @@ static struct dentry *debugfs_root; static int __init damon_debugfs_init(void) { - const char * const file_names[] = {"attrs", "record", "schemes", - "target_ids", "monitor_on"}; - const struct file_operations *fops[] = {&attrs_fops, &record_fops, - &schemes_fops, &target_ids_fops, &monitor_on_fops}; + const char * const file_names[] = {"attrs", "init_regions", "record", + "schemes", "target_ids", "monitor_on"}; + const struct file_operations *fops[] = {&attrs_fops, + &init_regions_fops, &record_fops, &schemes_fops, + &target_ids_fops, &monitor_on_fops}; int i; debugfs_root = debugfs_create_dir("damon", NULL); -- 2.17.1