Received: by 2002:a05:6a10:a0d1:0:0:0:0 with SMTP id j17csp2222856pxa; Mon, 17 Aug 2020 04:31:25 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwsxV2TlIQczOwSi189bAL83w0RS/fjSw3svmO/sbaobjoDenGD9wzvhE0ki5/OB3sRUPvf X-Received: by 2002:aa7:d387:: with SMTP id x7mr14230948edq.219.1597663885676; Mon, 17 Aug 2020 04:31:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1597663885; cv=none; d=google.com; s=arc-20160816; b=urJ/1hZXcsfmTKPRianMX5fNVplQYEI6UHKn05IQmhWd3BLllgRyQgK1ROOPHaWLQc rpGim2ANOb8RN17+zmm3/RunrcG7KmRAaFCdK/c+OqprfgTeVhOLIXGajRaa1Q7Q6tG0 vxG70N6a/VB4jYlodVl9GSKg+xLyQ8IS9hzeX0Bt2Dpfw/2k3G4vUJzneLZx8THfSZ48 iwQmJ+3dsHHcVxgVmKppJx3Kzt77eeUB1BMG0Dm/4xQJGY2JAF/w22FJwLbpqRZxeG2S dA3ZtgVRSc5cU8jnZy0pJ3AupQ5yTYYP/azAGkLpEaxzJOlnJHCCn34KD16aaor7i4lG POWw== 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=k6WU8X8uUioiTj7c3Ke/KLWkbXXGCVDmB5Ldj54XnIY=; b=roLoHsZvRlJWcJNhYHA11BheibNJxFUbsv3xUjjifshzhv9IR1owgfp0uGcJzlf33b aCav/zJ3kgH5b5Yin+Tzh64ynvd3Fr4729/rNKpBaJ8I85+V2G4KQjvq3nPHJZS3/HmY h5CJ5Dqbn9yJ3hJC1z5ZVuV+4BFdK6Zd9ryH6BMMYV1dQZRC/UYyU/hmpJZGQjjQm2vp cWhCMjosQRul6di0aTyZnKQ4ghCXKPxteqlu3w7ReCsr2eSd9ctD/1K3m0dmm4pQ+/XO NO8XDamKGm2AIUb6Io2wmLmGDLO8lyvMa5CK13QpUGxfroCIJbMS7zLlLsc1caT4k6NL fyBQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@amazon.com header.s=amazon201209 header.b=NGTENIgd; 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 p3si10632551edr.352.2020.08.17.04.31.02; Mon, 17 Aug 2020 04:31:25 -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=NGTENIgd; 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 S1728239AbgHQKzp (ORCPT + 99 others); Mon, 17 Aug 2020 06:55:45 -0400 Received: from smtp-fw-4101.amazon.com ([72.21.198.25]:49184 "EHLO smtp-fw-4101.amazon.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727868AbgHQKzJ (ORCPT ); Mon, 17 Aug 2020 06:55:09 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.com; i=@amazon.com; q=dns/txt; s=amazon201209; t=1597661707; x=1629197707; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=k6WU8X8uUioiTj7c3Ke/KLWkbXXGCVDmB5Ldj54XnIY=; b=NGTENIgdquIQBTZlcgbLwhGXyKSa7UPBLvT2xVd42HZRWmj0SHtkMCQg a4JvkW6hNS7EnkibW4fbyREhY2OVz7laCSqDsm5MnphWpjLoa+5RoAJuR otefM4a9kgJKOr/ZLYRdYoQZgdJPv59MxI/lfB6zshJiYt7qcvmeVMxvt U=; X-IronPort-AV: E=Sophos;i="5.76,322,1592870400"; d="scan'208";a="48282142" Received: from iad12-co-svc-p1-lb1-vlan3.amazon.com (HELO email-inbound-relay-1d-2c665b5d.us-east-1.amazon.com) ([10.43.8.6]) by smtp-border-fw-out-4101.iad4.amazon.com with ESMTP; 17 Aug 2020 10:55:06 +0000 Received: from EX13MTAUEA002.ant.amazon.com (iad55-ws-svc-p15-lb9-vlan2.iad.amazon.com [10.40.159.162]) by email-inbound-relay-1d-2c665b5d.us-east-1.amazon.com (Postfix) with ESMTPS id C9FDAA1BCE; Mon, 17 Aug 2020 10:54:54 +0000 (UTC) Received: from EX13D31EUA001.ant.amazon.com (10.43.165.15) by EX13MTAUEA002.ant.amazon.com (10.43.61.77) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Mon, 17 Aug 2020 10:54:53 +0000 Received: from u3f2cd687b01c55.ant.amazon.com (10.43.160.192) by EX13D31EUA001.ant.amazon.com (10.43.165.15) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Mon, 17 Aug 2020 10:54:37 +0000 From: SeongJae Park To: CC: SeongJae Park , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , Subject: [PATCH v20 07/15] mm/damon: Implement access pattern recording Date: Mon, 17 Aug 2020 12:51:29 +0200 Message-ID: <20200817105137.19296-8-sjpark@amazon.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200817105137.19296-1-sjpark@amazon.com> References: <20200817105137.19296-1-sjpark@amazon.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.43.160.192] X-ClientProxiedBy: EX13D02UWC004.ant.amazon.com (10.43.162.236) To EX13D31EUA001.ant.amazon.com (10.43.165.15) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: SeongJae Park This commit implements the recording feature of DAMON. If this feature is enabled, DAMON writes the monitored access patterns in its binary format into a file which specified by the user. This is already able to be implemented by each user using the callbacks. However, as the recording is expected to be widely used, this commit implements the feature in the DAMON, for more convenience. Signed-off-by: SeongJae Park Reviewed-by: Leonard Foerster --- include/linux/damon.h | 15 +++++ mm/damon.c | 142 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 154 insertions(+), 3 deletions(-) diff --git a/include/linux/damon.h b/include/linux/damon.h index 945eb9259acf..54cdc1366f59 100644 --- a/include/linux/damon.h +++ b/include/linux/damon.h @@ -75,6 +75,14 @@ struct damon_target { * in case of virtual memory monitoring) and applies the changes for each * @regions_update_interval. All time intervals are in micro-seconds. * + * @rbuf: In-memory buffer for monitoring result recording. + * @rbuf_len: The length of @rbuf. + * @rbuf_offset: The offset for next write to @rbuf. + * @rfile_path: Record file path. + * + * If @rbuf, @rbuf_len, and @rfile_path are set, the monitored results are + * automatically stored in @rfile_path file. + * * @kdamond: Kernel thread who does the monitoring. * @kdamond_stop: Notifies whether kdamond should stop. * @kdamond_lock: Mutex for the synchronizations with @kdamond. @@ -142,6 +150,11 @@ struct damon_ctx { struct timespec64 last_aggregation; struct timespec64 last_regions_update; + unsigned char *rbuf; + unsigned int rbuf_len; + unsigned int rbuf_offset; + char *rfile_path; + struct task_struct *kdamond; bool kdamond_stop; struct mutex kdamond_lock; @@ -172,6 +185,8 @@ int damon_set_targets(struct damon_ctx *ctx, 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_set_recording(struct damon_ctx *ctx, + unsigned int rbuf_len, char *rfile_path); 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.c b/mm/damon.c index cec151d60755..fed35f7b3879 100644 --- a/mm/damon.c +++ b/mm/damon.c @@ -57,6 +57,10 @@ #define damon_for_each_target_safe(t, next, ctx) \ list_for_each_entry_safe(t, next, &(ctx)->targets_list, list) +#define MIN_RECORD_BUFFER_LEN 1024 +#define MAX_RECORD_BUFFER_LEN (4 * 1024 * 1024) +#define MAX_RFILE_PATH_LEN 256 + /* Get a random number in [l, r) */ #define damon_rand(l, r) (l + prandom_u32() % (r - l)) @@ -785,16 +789,89 @@ static bool kdamond_aggregate_interval_passed(struct damon_ctx *ctx) } /* - * Reset the aggregated monitoring results + * Flush the content in the result buffer to the result file + */ +static void damon_flush_rbuffer(struct damon_ctx *ctx) +{ + ssize_t sz; + loff_t pos = 0; + struct file *rfile; + + if (!ctx->rbuf_offset) + return; + + rfile = filp_open(ctx->rfile_path, + O_CREAT | O_RDWR | O_APPEND | O_LARGEFILE, 0644); + if (IS_ERR(rfile)) { + pr_err("Cannot open the result file %s\n", + ctx->rfile_path); + return; + } + + while (ctx->rbuf_offset) { + sz = kernel_write(rfile, ctx->rbuf, ctx->rbuf_offset, &pos); + if (sz < 0) + break; + ctx->rbuf_offset -= sz; + } + filp_close(rfile, NULL); +} + +/* + * Write a data into the result buffer + */ +static void damon_write_rbuf(struct damon_ctx *ctx, void *data, ssize_t size) +{ + if (!ctx->rbuf_len || !ctx->rbuf || !ctx->rfile_path) + return; + if (ctx->rbuf_offset + size > ctx->rbuf_len) + damon_flush_rbuffer(ctx); + if (ctx->rbuf_offset + size > ctx->rbuf_len) { + pr_warn("%s: flush failed, or wrong size given(%u, %zu)\n", + __func__, ctx->rbuf_offset, size); + return; + } + + memcpy(&ctx->rbuf[ctx->rbuf_offset], data, size); + ctx->rbuf_offset += size; +} + +/* + * Flush the aggregated monitoring results to the result buffer + * + * Stores current tracking results to the result buffer and reset 'nr_accesses' + * of each region. The format for the result buffer is as below: + * + *