Received: by 2002:a05:6a10:8c0a:0:0:0:0 with SMTP id go10csp170236pxb; Tue, 2 Feb 2021 02:05:30 -0800 (PST) X-Google-Smtp-Source: ABdhPJxtkWTx2Jat2MzEfdgdX/kdgysIoIXw5O+M/G8SkGXt64f1esUWIT05KCjU4k+UU52cOJDy X-Received: by 2002:a17:906:128e:: with SMTP id k14mr21221621ejb.427.1612260330689; Tue, 02 Feb 2021 02:05:30 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1612260330; cv=none; d=google.com; s=arc-20160816; b=HFxpUULhksIQaNbfOq+x24dQxvoiu++r1NzaHsX13Elx0uh5A1QDIfdH0WbUqtQKeS NuPsGpqUvva4SYTjyOi+MyeBo7P8+1fLZOKTYSFTI7VbbEmBdmVMsPUsjmbsQ0/sEkSK buDIyihN8e06ktSP95eUS7A/ynQ7QpMblsWCrsnzs7joIA9xqkUfc59WY2vQ6DHnc41w 5MWe1lmlcnK2D/x/3dS7AesvU/qh12uPxPZeuJ/Rr7uWQ3ZsUQBoorQyhD3sN0vgG0Zo g8ihwWCQVpiTrSna5bVJZ8j1bpP7o7NtSQJabNXMPzDHtHNho2GkothYQResK37VP/QK jlWg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:in-reply-to:message-id:date:subject :cc:to:from:dkim-signature; bh=mLcP0izKWDNsLPjNz5dQdzdBpJthpi2P8wIHv6ID5/w=; b=NodDnXee1VMT3hH66LRY6vEPwD9f838e7uWjkAZ1O60qM61ssUv33z88wYEWZZsSu8 mqibJF4fKdzU3qgt/5um2hYpv6+NvhJ/6LhA6PjcHunJyLHuO/tsGaofviq0K8lFwmWU jX1gHU/kS3GO5nv7ADmC46fNpriQiSoZGRgRe6nB3qaRfu+ztPCFh1imaaU8JVY69NyD MsbEMvjE3+txWCW/coDLFwEJlpsVwNwAHObNHxMLJQ5+WnX95z2UQUHY5llrRDXODPTp 6bYRtW0NsLfvz92FCFGXQv6/hrfaylp3sHsvsknwpaUAldDTmUporNQ25cYBumDvJ3Qb SPJQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@amazon.com header.s=amazon201209 header.b=hm2MeAhp; 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 y8si2477491edp.207.2021.02.02.02.05.05; Tue, 02 Feb 2021 02:05:30 -0800 (PST) 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=hm2MeAhp; 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 S229902AbhBBKBx (ORCPT + 99 others); Tue, 2 Feb 2021 05:01:53 -0500 Received: from smtp-fw-4101.amazon.com ([72.21.198.25]:50782 "EHLO smtp-fw-4101.amazon.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229835AbhBBKBk (ORCPT ); Tue, 2 Feb 2021 05:01:40 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.com; i=@amazon.com; q=dns/txt; s=amazon201209; t=1612260098; x=1643796098; h=from:to:cc:subject:date:message-id:in-reply-to: mime-version; bh=mLcP0izKWDNsLPjNz5dQdzdBpJthpi2P8wIHv6ID5/w=; b=hm2MeAhprkWf7hS8QZQjxki5fBMPy2v45Yyxe7SNjKZ/JLPjV4zUfDXE pEo+wROFLqr2sMC3Lv/tsRTpeOiP58YvYm3EXvyOattBdeytVVEbFKu6X P7bWzxt8bt1bFdwS/Ou00urWlVsLsDWfuwU0rATjvtuC8qEabUVGOOdn6 I=; X-IronPort-AV: E=Sophos;i="5.79,394,1602547200"; d="scan'208";a="79240678" Received: from iad12-co-svc-p1-lb1-vlan2.amazon.com (HELO email-inbound-relay-2a-f14f4a47.us-west-2.amazon.com) ([10.43.8.2]) by smtp-border-fw-out-4101.iad4.amazon.com with ESMTP; 02 Feb 2021 10:00:48 +0000 Received: from EX13D31EUA001.ant.amazon.com (pdx1-ws-svc-p6-lb9-vlan2.pdx.amazon.com [10.236.137.194]) by email-inbound-relay-2a-f14f4a47.us-west-2.amazon.com (Postfix) with ESMTPS id 5B40AA2A0E; Tue, 2 Feb 2021 10:00:45 +0000 (UTC) Received: from u3f2cd687b01c55.ant.amazon.com (10.43.162.94) by EX13D31EUA001.ant.amazon.com (10.43.165.15) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Tue, 2 Feb 2021 10:00:28 +0000 From: SeongJae Park To: Shakeel Butt CC: SeongJae Park , SeongJae Park , , Andrea Arcangeli , , , , , , Brendan Higgins , Qian Cai , Colin Ian King , Jonathan Corbet , "David Hildenbrand" , , Marco Elver , "Du, Fan" , , "Greg Thelen" , Ian Rogers , , "Kirill A. Shutemov" , Mark Rutland , Mel Gorman , Minchan Kim , Ingo Molnar , , "Peter Zijlstra (Intel)" , Randy Dunlap , Rik van Riel , David Rientjes , Steven Rostedt , Mike Rapoport , , Shuah Khan , , , Vlastimil Babka , Vladimir Davydov , Yang Shi , Huang Ying , , , Linux MM , , LKML Subject: Re: [PATCH v23 07/15] mm/damon: Implement a debugfs-based user space interface Date: Tue, 2 Feb 2021 11:00:13 +0100 Message-ID: <20210202100013.9764-1-sjpark@amazon.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.43.162.94] X-ClientProxiedBy: EX13D31UWA002.ant.amazon.com (10.43.160.82) To EX13D31EUA001.ant.amazon.com (10.43.165.15) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, 1 Feb 2021 09:37:39 -0800 Shakeel Butt wrote: > On Tue, Dec 15, 2020 at 3:59 AM SeongJae Park wrote: > > > > From: SeongJae Park > > > > DAMON is designed to be used by kernel space code such as the memory > > management subsystems, and therefore it provides only kernel space API. > > Which kernel space APIs are being referred here? The symbols in 'include/linux/damon.h' > > > That said, letting the user space control DAMON could provide some > > benefits to them. For example, it will allow user space to analyze > > their specific workloads and make their own special optimizations. > > > > For such cases, this commit implements a simple DAMON application kernel > > module, namely 'damon-dbgfs', which merely wraps the DAMON api and > > exports those to the user space via the debugfs. > > [...] > > > > Signed-off-by: SeongJae Park > > Reviewed-by: Leonard Foerster > > --- > > include/linux/damon.h | 3 + > > mm/damon/Kconfig | 9 ++ > > mm/damon/Makefile | 1 + > > mm/damon/core.c | 45 ++++++ > > mm/damon/dbgfs.c | 366 ++++++++++++++++++++++++++++++++++++++++++ > > 5 files changed, 424 insertions(+) > > create mode 100644 mm/damon/dbgfs.c > > > > diff --git a/include/linux/damon.h b/include/linux/damon.h > > index 39b4d6d3ddee..f9e0d4349352 100644 > > --- a/include/linux/damon.h > > +++ b/include/linux/damon.h > > @@ -265,9 +265,12 @@ unsigned int damon_nr_regions(struct damon_target *t); > > > > struct damon_ctx *damon_new_ctx(enum damon_target_type type); > > void damon_destroy_ctx(struct damon_ctx *ctx); > > +int damon_set_targets(struct damon_ctx *ctx, > > + unsigned long *ids, ssize_t nr_ids); > > int damon_set_attrs(struct damon_ctx *ctx, unsigned long sample_int, > > unsigned long aggr_int, unsigned long regions_update_int, > > unsigned long min_nr_reg, unsigned long max_nr_reg); > > +int damon_nr_running_ctxs(void); > > > > int damon_start(struct damon_ctx **ctxs, int nr_ctxs); > > int damon_stop(struct damon_ctx **ctxs, int nr_ctxs); > > diff --git a/mm/damon/Kconfig b/mm/damon/Kconfig > > index 8ae080c52950..72f1683ba0ee 100644 > > --- a/mm/damon/Kconfig > > +++ b/mm/damon/Kconfig > > @@ -21,4 +21,13 @@ config DAMON_VADDR > > This builds the default data access monitoring primitives for DAMON > > that works for virtual address spaces. > > > > +config DAMON_DBGFS > > + bool "DAMON debugfs interface" > > + depends on DAMON_VADDR && DEBUG_FS > > + help > > + This builds the debugfs interface for DAMON. The user space admins > > + can use the interface for arbitrary data access monitoring. > > + > > + If unsure, say N. > > + > > endmenu > > diff --git a/mm/damon/Makefile b/mm/damon/Makefile > > index 6ebbd08aed67..fed4be3bace3 100644 > > --- a/mm/damon/Makefile > > +++ b/mm/damon/Makefile > > @@ -2,3 +2,4 @@ > > > > obj-$(CONFIG_DAMON) := core.o > > obj-$(CONFIG_DAMON_VADDR) += vaddr.o > > +obj-$(CONFIG_DAMON_DBGFS) += dbgfs.o > > diff --git a/mm/damon/core.c b/mm/damon/core.c > > index 5ca9f79ccbb6..b9575a6bebff 100644 > > --- a/mm/damon/core.c > > +++ b/mm/damon/core.c > > @@ -166,6 +166,37 @@ void damon_destroy_ctx(struct damon_ctx *ctx) > > kfree(ctx); > > } > > > > +/** > > + * damon_set_targets() - Set monitoring targets. > > + * @ctx: monitoring context > > + * @ids: array of target ids > > + * @nr_ids: number of entries in @ids > > + * > > + * This function should not be called while the kdamond is running. > > + * > > + * Return: 0 on success, negative error code otherwise. > > + */ > > +int damon_set_targets(struct damon_ctx *ctx, > > + unsigned long *ids, ssize_t nr_ids) > > +{ > > + ssize_t i; > > + struct damon_target *t, *next; > > + > > + damon_for_each_target_safe(t, next, ctx) > > + damon_destroy_target(t); > > You need to put the reference on the target before destroying. Oops, you're right. I will fix this in the next version. > > > + > > + for (i = 0; i < nr_ids; i++) { > > + t = damon_new_target(ids[i]); > > + if (!t) { > > + pr_err("Failed to alloc damon_target\n"); > > + return -ENOMEM; > > + } > > + damon_add_target(ctx, t); > > + } > > + > > + return 0; > > +} > > + > > /** > > * damon_set_attrs() - Set attributes for the monitoring. > > * @ctx: monitoring context > > @@ -206,6 +237,20 @@ int damon_set_attrs(struct damon_ctx *ctx, unsigned long sample_int, > > return 0; > > } > > > > +/** > > + * damon_nr_running_ctxs() - Return number of currently running contexts. > > + */ > > +int damon_nr_running_ctxs(void) > > +{ > > + int nr_ctxs; > > + > > + mutex_lock(&damon_lock); > > + nr_ctxs = nr_running_ctxs; > > + mutex_unlock(&damon_lock); > > READ_ONCE(nr_running_ctxs) ? I'd like to keep the code simpler to read, unless this turns out to be a real performance bottleneck. > > > + > > + return nr_ctxs; > > +} > > + [...] > > + > > +static ssize_t dbgfs_target_ids_write(struct file *file, > > + const char __user *buf, size_t count, loff_t *ppos) > > +{ > > + struct damon_ctx *ctx = file->private_data; > > + char *kbuf, *nrs; > > + unsigned long *targets; > > + ssize_t nr_targets; > > + ssize_t ret = count; > > + int i; > > + int err; > > + > > + kbuf = user_input_str(buf, count, ppos); > > + if (IS_ERR(kbuf)) > > + return PTR_ERR(kbuf); > > + > > + nrs = kbuf; > > + > > + targets = str_to_target_ids(nrs, ret, &nr_targets); > > + if (!targets) { > > + ret = -ENOMEM; > > + goto out; > > + } > > + > > + if (targetid_is_pid(ctx)) { > > + for (i = 0; i < nr_targets; i++) > > + targets[i] = (unsigned long)find_get_pid( > > + (int)targets[i]); > > + } > > + > > + mutex_lock(&ctx->kdamond_lock); > > + if (ctx->kdamond) { > > + ret = -EINVAL; > > + goto unlock_out; > > You need to put_pid on the targets array. Good catch! > > > + } > > + > > + err = damon_set_targets(ctx, targets, nr_targets); > > + if (err) > > + ret = err; > > You need to handle the partial failure from damon_set_targets(). My intention is to keep partial success as is. > > > > +unlock_out: > > + mutex_unlock(&ctx->kdamond_lock); > > + kfree(targets); > > +out: > > + kfree(kbuf); > > + return ret; > > +} [...] Thanks, SeongJae Park