Received: by 2002:a05:6a10:22f:0:0:0:0 with SMTP id 15csp2912685pxk; Mon, 28 Sep 2020 03:40:27 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyQ5Wfr3d8cxpVpLfxvkHJKqqD7EIO+PaKRIr8Y9+X1U/+9yipmKk/xDhjbJ7Y4p00SXyPL X-Received: by 2002:a17:906:4cc6:: with SMTP id q6mr971346ejt.201.1601289627445; Mon, 28 Sep 2020 03:40:27 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1601289627; cv=none; d=google.com; s=arc-20160816; b=IBLGJdrwKgW6yU6ltYgv9STpDPkvoOw1VrtD3TVPVP4aXuElcxjy0SUo7ODRqWXqzz xzekOOGDGjgiCmTXkn9Wu1er8/JTGT/DSdxNOdU6ogxEKodsHTqqH7PBrrg85ElMFEPk U4sFJzvxG6pluesndaDOr5N9TAFKpFnlyYioNyKFlF+E1Z3QJe0XN52uT1veCl1Qr9fW 8sHOpamzqWUxJsWduKL16/labIGvrRCCcoO8GiBOAUtmBf2wRLsw6H57JC05fNqkKak6 8Q/zlBUn1YRnnm/Lz8hi1cT73owwvw2uBKG157X0NG0KgKnnjQhE3sTDhVUkUBzsdBiB lIOw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=c/MK2pCSgOMGVOP2p7S4cmlEP6k8s8TkAwQl4lTQDDY=; b=LZwDk9TzZJx2ZdJH94oEgvuqN2g6IeryxqsdZe89DguvgcOgsV/sfcwssJr2hLPJoA oc5HQmnVHZkT2NtVtNhQh90oMlRPFJHbYKvGQWLL+jAQhDIi1LGmhQJCqRDjsMD5Jbht oiw9AX7VPIst0vpZ5MDN0CG/dmUFqX1QlKqrTAdZK9DuLVxn4TCUwiTjY4FmeR7ImA7P C3YyA1Jw6LW2Q23huH6UUvoIwY2rcgBJGYR1sXkewvIVnweJfeYCi8wVj3XHHl85Du52 g4OdiB2SAhZKGykHPE+Sq0zE+gBYV4wV7Cv7fNoZt8nAYXHOcoXlHXqGBrwx5QS4uvtc Ys7g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@amazon.com header.s=amazon201209 header.b=tbJlE3Cc; 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 j12si339316ejy.198.2020.09.28.03.40.04; Mon, 28 Sep 2020 03:40:27 -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=tbJlE3Cc; 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 S1726629AbgI1Kg6 (ORCPT + 99 others); Mon, 28 Sep 2020 06:36:58 -0400 Received: from smtp-fw-6002.amazon.com ([52.95.49.90]:13559 "EHLO smtp-fw-6002.amazon.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726552AbgI1Kg5 (ORCPT ); Mon, 28 Sep 2020 06:36:57 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.com; i=@amazon.com; q=dns/txt; s=amazon201209; t=1601289416; x=1632825416; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=c/MK2pCSgOMGVOP2p7S4cmlEP6k8s8TkAwQl4lTQDDY=; b=tbJlE3CcVuNa1n7weeepTnRud12OB7gTNHEsVLdebpXLFwvH4VnPr9Ah SEZ3PKs7+s6LkNSRVUvIclyV/bnXtwV8G2ZIJ1V5IK5jf5GUT0mbeMGQF 9rjAV603HQj9ScqTvrydns+NxB1eXORDQCXGS0ox+5l2LluXteVU/sMnj U=; X-IronPort-AV: E=Sophos;i="5.77,313,1596499200"; d="scan'208";a="56638137" Received: from iad12-co-svc-p1-lb1-vlan3.amazon.com (HELO email-inbound-relay-1a-715bee71.us-east-1.amazon.com) ([10.43.8.6]) by smtp-border-fw-out-6002.iad6.amazon.com with ESMTP; 28 Sep 2020 10:36:56 +0000 Received: from EX13D31EUA001.ant.amazon.com (iad12-ws-svc-p26-lb9-vlan3.iad.amazon.com [10.40.163.38]) by email-inbound-relay-1a-715bee71.us-east-1.amazon.com (Postfix) with ESMTPS id AE83DA1DB6; Mon, 28 Sep 2020 10:36:43 +0000 (UTC) Received: from u3f2cd687b01c55.ant.amazon.com (10.43.161.237) by EX13D31EUA001.ant.amazon.com (10.43.165.15) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Mon, 28 Sep 2020 10:36:25 +0000 From: SeongJae Park To: CC: SeongJae Park , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , Subject: [RFC PATCH 2/5] mm/damon: Separate DAMON schemes application to primitives Date: Mon, 28 Sep 2020 12:35:25 +0200 Message-ID: <20200928103528.4256-3-sjpark@amazon.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200928103528.4256-1-sjpark@amazon.com> References: <20200928103528.4256-1-sjpark@amazon.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.43.161.237] X-ClientProxiedBy: EX13D10UWA003.ant.amazon.com (10.43.160.248) To EX13D31EUA001.ant.amazon.com (10.43.165.15) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: SeongJae Park DAMON-based operation schemes feature is implemented inside DAMON 'core'. Though the access pattern based schemes target region tracking part makes sense to reside in the 'core', applying the scheme action would better to be reside in the 'primitives', as the work highly depends on the type of the target region. For the reason, this commit moves the part to 'primitives' by adding one more context callback, 'apply_scheme' and implementing it in the reference primitives implementation for the virtual address spaces. Note that this doesn't add the implementation for the physical address space, as it didn't exist before. Nonetheless, the extension for physical space would be easily done in this way in future. Signed-off-by: SeongJae Park --- include/linux/damon.h | 8 +++++ mm/damon/core.c | 65 ++------------------------------------ mm/damon/damon.h | 28 ----------------- mm/damon/primitives.c | 73 ++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 82 insertions(+), 92 deletions(-) diff --git a/include/linux/damon.h b/include/linux/damon.h index 264958a62c02..505e6261cefa 100644 --- a/include/linux/damon.h +++ b/include/linux/damon.h @@ -170,6 +170,7 @@ struct damos { * @check_accesses: Checks the access of target regions. * @target_valid: Determine if the target is valid. * @cleanup: Cleans up the context. + * @apply_scheme: Apply a DAMON-based operation scheme. * @sample_cb: Called for each sampling interval. * @aggregate_cb: Called for each aggregation interval. * @@ -193,6 +194,9 @@ struct damos { * monitoring. * @cleanup is called from @kdamond just before its termination. After this * call, only @kdamond_lock and @kdamond will be touched. + * @apply_scheme is called from @kdamond when a region for user provided + * DAMON-based operation scheme is found. It should apply the scheme's action + * to the region. * * @sample_cb and @aggregate_cb are called from @kdamond for each of the * sampling intervals and aggregation intervals, respectively. Therefore, @@ -229,6 +233,8 @@ struct damon_ctx { unsigned int (*check_accesses)(struct damon_ctx *context); bool (*target_valid)(struct damon_target *target); void (*cleanup)(struct damon_ctx *context); + int (*apply_scheme)(struct damon_ctx *context, struct damon_target *t, + struct damon_region *r, struct damos *scheme); void (*sample_cb)(struct damon_ctx *context); void (*aggregate_cb)(struct damon_ctx *context); }; @@ -312,6 +318,8 @@ void kdamond_prepare_vm_access_checks(struct damon_ctx *ctx); unsigned int kdamond_check_vm_accesses(struct damon_ctx *ctx); bool kdamond_vm_target_valid(struct damon_target *t); void kdamond_vm_cleanup(struct damon_ctx *ctx); +int kdamond_vm_apply_scheme(struct damon_ctx *context, struct damon_target *t, + struct damon_region *r, struct damos *scheme); void damon_set_vaddr_primitives(struct damon_ctx *ctx); /* Reference callback implementations for physical memory */ diff --git a/mm/damon/core.c b/mm/damon/core.c index d85ade7b5e23..ba52421a2673 100644 --- a/mm/damon/core.c +++ b/mm/damon/core.c @@ -701,68 +701,6 @@ static void kdamond_reset_aggregated(struct damon_ctx *c) } } -#ifndef CONFIG_ADVISE_SYSCALLS -static int damos_madvise(struct damon_target *target, struct damon_region *r, - int behavior) -{ - return -EINVAL; -} -#else -static int damos_madvise(struct damon_target *target, struct damon_region *r, - int behavior) -{ - struct task_struct *t; - struct mm_struct *mm; - int ret = -ENOMEM; - - t = damon_get_task_struct(target); - if (!t) - goto out; - mm = damon_get_mm(target); - if (!mm) - goto put_task_out; - - ret = do_madvise(t, mm, PAGE_ALIGN(r->ar.start), - PAGE_ALIGN(r->ar.end - r->ar.start), behavior); - mmput(mm); -put_task_out: - put_task_struct(t); -out: - return ret; -} -#endif /* CONFIG_ADVISE_SYSCALLS */ - -static int damos_do_action(struct damon_target *target, struct damon_region *r, - enum damos_action action) -{ - int madv_action; - - switch (action) { - case DAMOS_WILLNEED: - madv_action = MADV_WILLNEED; - break; - case DAMOS_COLD: - madv_action = MADV_COLD; - break; - case DAMOS_PAGEOUT: - madv_action = MADV_PAGEOUT; - break; - case DAMOS_HUGEPAGE: - madv_action = MADV_HUGEPAGE; - break; - case DAMOS_NOHUGEPAGE: - madv_action = MADV_NOHUGEPAGE; - break; - case DAMOS_STAT: - return 0; - default: - pr_warn("Wrong action %d\n", action); - return -EINVAL; - } - - return damos_madvise(target, r, madv_action); -} - static void damon_do_apply_schemes(struct damon_ctx *c, struct damon_target *t, struct damon_region *r) @@ -781,7 +719,8 @@ static void damon_do_apply_schemes(struct damon_ctx *c, continue; s->stat_count++; s->stat_sz += sz; - damos_do_action(t, r, s->action); + if (c->apply_scheme) + c->apply_scheme(c, t, r, s); if (s->action != DAMOS_STAT) r->age = 0; } diff --git a/mm/damon/damon.h b/mm/damon/damon.h index fc565fff4953..4315dadcca8a 100644 --- a/mm/damon/damon.h +++ b/mm/damon/damon.h @@ -5,31 +5,3 @@ /* Get a random number in [l, r) */ #define damon_rand(l, r) (l + prandom_u32() % (r - l)) - -/* - * 't->id' should be the pointer to the relevant 'struct pid' having reference - * count. Caller must put the returned task, unless it is NULL. - */ -#define damon_get_task_struct(t) \ - (get_pid_task((struct pid *)t->id, PIDTYPE_PID)) - -/* - * Get the mm_struct of the given target - * - * Caller _must_ put the mm_struct after use, unless it is NULL. - * - * Returns the mm_struct of the target on success, NULL on failure - */ -static inline struct mm_struct *damon_get_mm(struct damon_target *t) -{ - struct task_struct *task; - struct mm_struct *mm; - - task = damon_get_task_struct(t); - if (!task) - return NULL; - - mm = get_task_mm(task); - put_task_struct(task); - return mm; -} diff --git a/mm/damon/primitives.c b/mm/damon/primitives.c index d7796cbffbd8..e762dc8a5f2e 100644 --- a/mm/damon/primitives.c +++ b/mm/damon/primitives.c @@ -38,8 +38,11 @@ #endif /* - * Functions for the initial monitoring target regions construction + * 't->id' should be the pointer to the relevant 'struct pid' having reference + * count. Caller must put the returned task, unless it is NULL. */ +#define damon_get_task_struct(t) \ + (get_pid_task((struct pid *)t->id, PIDTYPE_PID)) /* * Get the mm_struct of the given target @@ -62,6 +65,10 @@ struct mm_struct *damon_get_mm(struct damon_target *t) return mm; } +/* + * Functions for the initial monitoring target regions construction + */ + /* * Size-evenly split a region into 'nr_pieces' small regions * @@ -788,6 +795,68 @@ void kdamond_vm_cleanup(struct damon_ctx *ctx) } } +#ifndef CONFIG_ADVISE_SYSCALLS +static int damos_madvise(struct damon_target *target, struct damon_region *r, + int behavior) +{ + return -EINVAL; +} +#else +static int damos_madvise(struct damon_target *target, struct damon_region *r, + int behavior) +{ + struct task_struct *t; + struct mm_struct *mm; + int ret = -ENOMEM; + + t = damon_get_task_struct(target); + if (!t) + goto out; + mm = damon_get_mm(target); + if (!mm) + goto put_task_out; + + ret = do_madvise(t, mm, PAGE_ALIGN(r->ar.start), + PAGE_ALIGN(r->ar.end - r->ar.start), behavior); + mmput(mm); +put_task_out: + put_task_struct(t); +out: + return ret; +} +#endif /* CONFIG_ADVISE_SYSCALLS */ + +int kdamond_vm_apply_scheme(struct damon_ctx *ctx, struct damon_target *t, + struct damon_region *r, struct damos *scheme) +{ + int madv_action; + + switch (scheme->action) { + case DAMOS_WILLNEED: + madv_action = MADV_WILLNEED; + break; + case DAMOS_COLD: + madv_action = MADV_COLD; + break; + case DAMOS_PAGEOUT: + madv_action = MADV_PAGEOUT; + break; + case DAMOS_HUGEPAGE: + madv_action = MADV_HUGEPAGE; + break; + case DAMOS_NOHUGEPAGE: + madv_action = MADV_NOHUGEPAGE; + break; + case DAMOS_STAT: + return 0; + default: + pr_warn("Wrong action %d\n", scheme->action); + return -EINVAL; + } + + return damos_madvise(t, r, madv_action); +} + void damon_set_vaddr_primitives(struct damon_ctx *ctx) { ctx->init_target_regions = kdamond_init_vm_regions; @@ -796,6 +865,7 @@ void damon_set_vaddr_primitives(struct damon_ctx *ctx) ctx->check_accesses = kdamond_check_vm_accesses; ctx->target_valid = kdamond_vm_target_valid; ctx->cleanup = kdamond_vm_cleanup; + ctx->apply_scheme = kdamond_vm_apply_scheme; } void damon_set_paddr_primitives(struct damon_ctx *ctx) @@ -806,6 +876,7 @@ void damon_set_paddr_primitives(struct damon_ctx *ctx) ctx->check_accesses = kdamond_check_phys_accesses; ctx->target_valid = NULL; ctx->cleanup = NULL; + ctx->apply_scheme = NULL; } #include "primitives-test.h" -- 2.17.1