Received: by 2002:a05:6a10:f3d0:0:0:0:0 with SMTP id a16csp3526210pxv; Mon, 28 Jun 2021 06:38:58 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwwJ63g9oMotQXx+JXEey8wYwC2bBPeNfL4Ihq0YCWmbXc4KMs1+sGGzZPaaOvERJ83JMM7 X-Received: by 2002:aa7:d413:: with SMTP id z19mr33610253edq.37.1624887538652; Mon, 28 Jun 2021 06:38:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1624887538; cv=none; d=google.com; s=arc-20160816; b=JAb3iw0dObUkQivv4w+P7VHSM5H2yudsCNWgbPfeHMz3OzvHIvdUlC7TIWaRv2WCgf AIVk5Bol5BV6NUHZnCPektT9IdV3YYWqzH/vZT0RgQyKaP0B8YvsupDxDBN5r7AWHFV1 sJu/uoyyU/SqGusul7ihYHBhD7fhWEAxrYFsl2CaHjLFJK8IMzEpV8SbbWUi+XJx8YW/ LMNemwa/CTVgx06DXMDaypP0LzIFKBoil9AHr5b9FEQ7ZPynKPyiPrQDxRGaAhZ30MlF Vh9F/70njXUDG5qSYMplHXRjTPVohSyLTkxu8XHTDZ95IUAqvz4IuP8oVb9IMYhr3ukM WJHQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:references:in-reply-to:message-id:date:subject :cc:to:from:dkim-signature; bh=fq1ZoPC42eMqWQGbnrLrlL4Ve1LVuhTF5O3t1T5h2G8=; b=vTy/CVPDUz6gimMklxaEhiZB90K/DEtUrhANssWBsnOGKSbVgHXhUJw2cyj3OrCUE2 fsg5zbeIpkAxOa1z9di1Kk94s0rU8GxDvLqeKj5qgoqWUQ+FpaKsadPWplTitZy6zu+8 Efc7khkaEeGs1HTXiFS9892XvwikQxCpPY0nMq8F+mv+HolBv57RGDsdemX3Oj16XgAm EdHN9GS8AGbmPoqrP+rdXeSrpTC9mZTLDqTJ0hIVHSvQeZMcUKiyEyMSN6sUXsXfyEZO TOD8+k92sxB8D0LJ+Ne+eQDAerHtnmBAabP7rBV/lFfsnTsu0g5Q7W10TQqBfLAa4M2r jcKg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=F6IN7JoW; 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=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id e6si13646459ejm.89.2021.06.28.06.38.31; Mon, 28 Jun 2021 06:38:58 -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=@gmail.com header.s=20161025 header.b=F6IN7JoW; 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=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232246AbhF1Nh0 (ORCPT + 99 others); Mon, 28 Jun 2021 09:37:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52068 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232065AbhF1Ngy (ORCPT ); Mon, 28 Jun 2021 09:36:54 -0400 Received: from mail-qt1-x82d.google.com (mail-qt1-x82d.google.com [IPv6:2607:f8b0:4864:20::82d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C612DC0613A3; Mon, 28 Jun 2021 06:34:26 -0700 (PDT) Received: by mail-qt1-x82d.google.com with SMTP id r7so13520129qta.12; Mon, 28 Jun 2021 06:34:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=fq1ZoPC42eMqWQGbnrLrlL4Ve1LVuhTF5O3t1T5h2G8=; b=F6IN7JoWPwKi3v5VV1j4VOMcZZnYpQzYzMHGXL+YMwe2nvKENxEf0AsSx6UOGEeoGp 6gRDYhdQ7ev1LMxuxEdQ8UDnhXgtMbW/LuzbnH/AQWVwpDHhgPJQPrzz3zJiGaQwZan6 xXKTG9/oox0K5CjMzzYpdfFxMNs+aqvm4vGqdtUvwTKxrMBXqAeXcYpHqTovSNLP7vpp VMpNXsh56DXU5ggEq8N3SlWUz2lA53m7oZcPuzLx8bZIUyH6Ez4Y64NX+0VD9FjpJPFa Erd6ukxwFtMLU/S0x4BKBdsSlcB/U+gELobeZBPuzZ6GDrz3vb4UerC3cY3PuWW5QsJS Gjfg== 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:in-reply-to :references; bh=fq1ZoPC42eMqWQGbnrLrlL4Ve1LVuhTF5O3t1T5h2G8=; b=q/pOFw/lpeB7AmoKPWGI8rzG9Sr2LU5j9YTMCRgHmvUECBtmP+ItpD1afh6GpvbZZ3 3xC4mUKC2V+dldxOQRm51AJeURY+HqVJ6LUKU8zsMRWgQLMHrHhnKd1N26luBkLTv8Sj 18hPJh+X5UEHFmQMiq+Pau7fzqZt/3Tda+Luf7LfYOrrJ27Hbwsm2eouulpfK7XcH3xj BBSHOP3JB4gEmgr5xEKoLnbvLvvPphFVYpug7Y7kCh6d9wOlrJKp1B3y/7b0p6d/iS+z g7O837zQH+ZnMXUcT8/xW6wL9kwRZAZiZw+8f+jubUhuoJIwFho2RNJqv0zbRIIWywNs AJew== X-Gm-Message-State: AOAM532kKm8HMiiyyEBK51MX0eXox2eGzhCv6KI7Wave+zNTdp6bhwPt bjTwQluaWuS6uECxMDFPWiY= X-Received: by 2002:ac8:7499:: with SMTP id v25mr260940qtq.65.1624887265926; Mon, 28 Jun 2021 06:34:25 -0700 (PDT) Received: from localhost.localdomain (ec2-35-169-212-159.compute-1.amazonaws.com. [35.169.212.159]) by smtp.gmail.com with ESMTPSA id h1sm2276030qkm.50.2021.06.28.06.34.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Jun 2021 06:34:25 -0700 (PDT) From: SeongJae Park To: akpm@linux-foundation.org Cc: SeongJae Park , Jonathan.Cameron@Huawei.com, acme@kernel.org, alexander.shishkin@linux.intel.com, amit@kernel.org, benh@kernel.crashing.org, brendanhiggins@google.com, corbet@lwn.net, david@redhat.com, dwmw@amazon.com, elver@google.com, fan.du@intel.com, foersleo@amazon.de, greg@kroah.com, gthelen@google.com, guoju.fgj@alibaba-inc.com, jgowans@amazon.com, mgorman@suse.de, mheyne@amazon.de, minchan@kernel.org, mingo@redhat.com, namhyung@kernel.org, peterz@infradead.org, riel@surriel.com, rientjes@google.com, rostedt@goodmis.org, rppt@kernel.org, shakeelb@google.com, shuah@kernel.org, sieberf@amazon.com, sj38.park@gmail.com, snu@zelle79.org, vbabka@suse.cz, vdavydov.dev@gmail.com, zgf574564920@gmail.com, linux-damon@amazon.com, linux-mm@kvack.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v32 09/13] mm/damon/dbgfs: Support multiple contexts Date: Mon, 28 Jun 2021 13:33:51 +0000 Message-Id: <20210628133355.18576-10-sj38.park@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210628133355.18576-1-sj38.park@gmail.com> References: <20210628133355.18576-1-sj38.park@gmail.com> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: SeongJae Park In some use cases, users would want to run multiple monitoring context. For example, if a user wants a high precision monitoring and dedicating multiple CPUs for the job is ok, because DAMON creates one monitoring thread per one context, the user can split the monitoring target regions into multiple small regions and create one context for each region. Or, someone might want to simultaneously monitor different address spaces, e.g., both virtual address space and physical address space. The DAMON's API allows such usage, but 'damon-dbgfs' does not. Therefore, only kernel space DAMON users can do multiple contexts monitoring. This commit allows the user space DAMON users to use multiple contexts monitoring by introducing two new 'damon-dbgfs' debugfs files, 'mk_context' and 'rm_context'. Users can create a new monitoring context by writing the desired name of the new context to 'mk_context'. Then, a new directory with the name and having the files for setting of the context ('attrs', 'target_ids' and 'record') will be created under the debugfs directory. Writing the name of the context to remove to 'rm_context' will remove the related context and directory. Signed-off-by: SeongJae Park Reviewed-by: Fernand Sieber --- mm/damon/dbgfs.c | 195 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 193 insertions(+), 2 deletions(-) diff --git a/mm/damon/dbgfs.c b/mm/damon/dbgfs.c index bd9bc6ede40e..cd2cc0a9c52a 100644 --- a/mm/damon/dbgfs.c +++ b/mm/damon/dbgfs.c @@ -18,6 +18,7 @@ static struct damon_ctx **dbgfs_ctxs; static int dbgfs_nr_ctxs; static struct dentry **dbgfs_dirs; +static DEFINE_MUTEX(damon_dbgfs_lock); /* * Returns non-empty string on success, negative error code otherwise. @@ -326,6 +327,186 @@ static struct damon_ctx *dbgfs_new_ctx(void) return ctx; } +static void dbgfs_destroy_ctx(struct damon_ctx *ctx) +{ + damon_destroy_ctx(ctx); +} + +/* + * Make a context of @name and create a debugfs directory for it. + * + * This function should be called while holding damon_dbgfs_lock. + * + * Returns 0 on success, negative error code otherwise. + */ +static int dbgfs_mk_context(char *name) +{ + struct dentry *root, **new_dirs, *new_dir; + struct damon_ctx **new_ctxs, *new_ctx; + + if (damon_nr_running_ctxs()) + return -EBUSY; + + new_ctxs = krealloc(dbgfs_ctxs, sizeof(*dbgfs_ctxs) * + (dbgfs_nr_ctxs + 1), GFP_KERNEL); + if (!new_ctxs) + return -ENOMEM; + dbgfs_ctxs = new_ctxs; + + new_dirs = krealloc(dbgfs_dirs, sizeof(*dbgfs_dirs) * + (dbgfs_nr_ctxs + 1), GFP_KERNEL); + if (!new_dirs) + return -ENOMEM; + dbgfs_dirs = new_dirs; + + root = dbgfs_dirs[0]; + if (!root) + return -ENOENT; + + new_dir = debugfs_create_dir(name, root); + dbgfs_dirs[dbgfs_nr_ctxs] = new_dir; + + new_ctx = dbgfs_new_ctx(); + if (!new_ctx) { + debugfs_remove(new_dir); + dbgfs_dirs[dbgfs_nr_ctxs] = NULL; + return -ENOMEM; + } + + dbgfs_ctxs[dbgfs_nr_ctxs] = new_ctx; + dbgfs_fill_ctx_dir(dbgfs_dirs[dbgfs_nr_ctxs], + dbgfs_ctxs[dbgfs_nr_ctxs]); + dbgfs_nr_ctxs++; + + return 0; +} + +static ssize_t dbgfs_mk_context_write(struct file *file, + const char __user *buf, size_t count, loff_t *ppos) +{ + char *kbuf; + char *ctx_name; + ssize_t ret = count; + int err; + + kbuf = user_input_str(buf, count, ppos); + if (IS_ERR(kbuf)) + return PTR_ERR(kbuf); + ctx_name = kmalloc(count + 1, GFP_KERNEL); + if (!ctx_name) { + kfree(kbuf); + return -ENOMEM; + } + + /* Trim white space */ + if (sscanf(kbuf, "%s", ctx_name) != 1) { + ret = -EINVAL; + goto out; + } + + mutex_lock(&damon_dbgfs_lock); + err = dbgfs_mk_context(ctx_name); + if (err) + ret = err; + mutex_unlock(&damon_dbgfs_lock); + +out: + kfree(kbuf); + kfree(ctx_name); + return ret; +} + +/* + * Remove a context of @name and its debugfs directory. + * + * This function should be called while holding damon_dbgfs_lock. + * + * Return 0 on success, negative error code otherwise. + */ +static int dbgfs_rm_context(char *name) +{ + struct dentry *root, *dir, **new_dirs; + struct damon_ctx **new_ctxs; + int i, j; + + if (damon_nr_running_ctxs()) + return -EBUSY; + + root = dbgfs_dirs[0]; + if (!root) + return -ENOENT; + + dir = debugfs_lookup(name, root); + if (!dir) + return -ENOENT; + + new_dirs = kmalloc_array(dbgfs_nr_ctxs - 1, sizeof(*dbgfs_dirs), + GFP_KERNEL); + if (!new_dirs) + return -ENOMEM; + + new_ctxs = kmalloc_array(dbgfs_nr_ctxs - 1, sizeof(*dbgfs_ctxs), + GFP_KERNEL); + if (!new_ctxs) { + kfree(new_dirs); + return -ENOMEM; + } + + for (i = 0, j = 0; i < dbgfs_nr_ctxs; i++) { + if (dbgfs_dirs[i] == dir) { + debugfs_remove(dbgfs_dirs[i]); + dbgfs_destroy_ctx(dbgfs_ctxs[i]); + continue; + } + new_dirs[j] = dbgfs_dirs[i]; + new_ctxs[j++] = dbgfs_ctxs[i]; + } + + kfree(dbgfs_dirs); + kfree(dbgfs_ctxs); + + dbgfs_dirs = new_dirs; + dbgfs_ctxs = new_ctxs; + dbgfs_nr_ctxs--; + + return 0; +} + +static ssize_t dbgfs_rm_context_write(struct file *file, + const char __user *buf, size_t count, loff_t *ppos) +{ + char *kbuf; + ssize_t ret = count; + int err; + char *ctx_name; + + kbuf = user_input_str(buf, count, ppos); + if (IS_ERR(kbuf)) + return PTR_ERR(kbuf); + ctx_name = kmalloc(count + 1, GFP_KERNEL); + if (!ctx_name) { + kfree(kbuf); + return -ENOMEM; + } + + /* Trim white space */ + if (sscanf(kbuf, "%s", ctx_name) != 1) { + ret = -EINVAL; + goto out; + } + + mutex_lock(&damon_dbgfs_lock); + err = dbgfs_rm_context(ctx_name); + if (err) + ret = err; + mutex_unlock(&damon_dbgfs_lock); + +out: + kfree(kbuf); + kfree(ctx_name); + return ret; +} + static ssize_t dbgfs_monitor_on_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { @@ -368,6 +549,14 @@ static ssize_t dbgfs_monitor_on_write(struct file *file, return ret; } +static const struct file_operations mk_contexts_fops = { + .write = dbgfs_mk_context_write, +}; + +static const struct file_operations rm_contexts_fops = { + .write = dbgfs_rm_context_write, +}; + static const struct file_operations monitor_on_fops = { .read = dbgfs_monitor_on_read, .write = dbgfs_monitor_on_write, @@ -376,8 +565,10 @@ static const struct file_operations monitor_on_fops = { static int __init __damon_dbgfs_init(void) { struct dentry *dbgfs_root; - const char * const file_names[] = {"monitor_on"}; - const struct file_operations *fops[] = {&monitor_on_fops}; + const char * const file_names[] = {"mk_contexts", "rm_contexts", + "monitor_on"}; + const struct file_operations *fops[] = {&mk_contexts_fops, + &rm_contexts_fops, &monitor_on_fops}; int i; dbgfs_root = debugfs_create_dir("damon", NULL); -- 2.17.1