From patchwork Wed Jun 14 17:37:37 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 9787121 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 2C7D260325 for ; Wed, 14 Jun 2017 17:38:05 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 157AE1FF13 for ; Wed, 14 Jun 2017 17:38:05 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0A7302684F; Wed, 14 Jun 2017 17:38:05 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 61A6C26861 for ; Wed, 14 Jun 2017 17:38:03 +0000 (UTC) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 5DCB121A143D0; Wed, 14 Jun 2017 10:36:47 -0700 (PDT) X-Original-To: intel-sgx-kernel-dev@lists.01.org Delivered-To: intel-sgx-kernel-dev@lists.01.org Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 251FD21BB2529 for ; Wed, 14 Jun 2017 10:36:45 -0700 (PDT) Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 14 Jun 2017 10:37:46 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.39,341,1493708400"; d="scan'208";a="113210044" Received: from sjchrist-ts.jf.intel.com ([10.54.74.20]) by orsmga005.jf.intel.com with ESMTP; 14 Jun 2017 10:37:45 -0700 From: Sean Christopherson To: intel-sgx-kernel-dev@lists.01.org Date: Wed, 14 Jun 2017 10:37:37 -0700 Message-Id: <1497461858-20309-12-git-send-email-sean.j.christopherson@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1497461858-20309-1-git-send-email-sean.j.christopherson@intel.com> References: <1497461858-20309-1-git-send-email-sean.j.christopherson@intel.com> Subject: [intel-sgx-kernel-dev] [RFC][PATCH 11/12] intel_sgx: add stats and events interfaces to EPC cgroup controller X-BeenThere: intel-sgx-kernel-dev@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: "Project: Intel® Software Guard Extensions for Linux*: https://01.org/intel-software-guard-extensions" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-sgx-kernel-dev-bounces@lists.01.org Sender: "intel-sgx-kernel-dev" X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Sean Christopherson --- drivers/platform/x86/intel_sgx/sgx_epc_cgroup.c | 84 +++++++++++++++++++++++-- drivers/platform/x86/intel_sgx/sgx_epc_cgroup.h | 83 ++++++++++++++++++++++++ drivers/platform/x86/intel_sgx/sgx_page_cache.c | 9 +++ 3 files changed, 172 insertions(+), 4 deletions(-) diff --git a/drivers/platform/x86/intel_sgx/sgx_epc_cgroup.c b/drivers/platform/x86/intel_sgx/sgx_epc_cgroup.c index 273555c..6b1d299 100644 --- a/drivers/platform/x86/intel_sgx/sgx_epc_cgroup.c +++ b/drivers/platform/x86/intel_sgx/sgx_epc_cgroup.c @@ -240,8 +240,11 @@ static bool sgx_epc_cgroup_lru_empty(struct sgx_epc_cgroup *root) static unsigned long sgx_epc_cgroup_swap_pages(unsigned long nr_pages, unsigned int flags, - struct sgx_epc_cgroup *epc_cg) + struct sgx_epc_cgroup *epc_cg, + enum sgx_epc_cgroup_counter c) { + sgx_epc_cgroup_event(epc_cg, c, 1); + /* * Ensure sgx_swap_pages is called with a minimum and maximum * number of pages. Attempting to swap only a few pages will @@ -258,14 +261,16 @@ static inline unsigned long sgx_epc_cgroup_swap_max(unsigned long nr_pages, unsigned int flags, struct sgx_epc_cgroup *epc_cg) { - return sgx_epc_cgroup_swap_pages(nr_pages, flags, epc_cg); + return sgx_epc_cgroup_swap_pages(nr_pages, flags, epc_cg, + SGX_EPC_CGROUP_MAX); } static inline unsigned long sgx_epc_cgroup_swap_high(unsigned long nr_pages, unsigned int flags, struct sgx_epc_cgroup *epc_cg) { - return sgx_epc_cgroup_swap_pages(nr_pages, flags, epc_cg); + return sgx_epc_cgroup_swap_pages(nr_pages, flags, epc_cg, + SGX_EPC_CGROUP_HIGH); } static void sgx_epc_cgroup_reclaim_high(struct sgx_epc_cgroup *epc_cg) @@ -436,8 +441,10 @@ int sgx_epc_cgroup_try_charge(struct mm_struct *mm, ret = __sgx_epc_cgroup_try_charge(epc_cg, alloc_flags, nr_pages); css_put(&epc_cg->css); - if (!ret) + if (!ret) { *epc_cg_ptr = epc_cg; + sgx_epc_cgroup_cnt_add(epc_cg, SGX_EPC_CGROUP_PAGES, nr_pages); + } return ret; } @@ -456,6 +463,7 @@ void sgx_epc_cgroup_uncharge(struct sgx_epc_cgroup *epc_cg, return; page_counter_uncharge(&epc_cg->pc, nr_pages); + sgx_epc_cgroup_cnt_sub(epc_cg, SGX_EPC_CGROUP_PAGES, nr_pages); if (epc_cg != root_epc_cgroup) css_put_many(&epc_cg->css, nr_pages); @@ -592,6 +600,62 @@ static u64 sgx_epc_current_read(struct cgroup_subsys_state *css, return (u64)page_counter_read(&epc_cg->pc) * PAGE_SIZE; } +static int sgx_epc_stats_show(struct seq_file *m, void *v) +{ + struct sgx_epc_cgroup *epc_cg = sgx_epc_cgroup_from_css(seq_css(m)); + + unsigned long cur, dir, rec, recs; + cur = page_counter_read(&epc_cg->pc); + dir = sgx_epc_cgroup_cnt_read(epc_cg, SGX_EPC_CGROUP_PAGES); + rec = sgx_epc_cgroup_cnt_read(epc_cg, SGX_EPC_CGROUP_RECLAIMED); + recs= sgx_epc_cgroup_cnt_read(epc_cg, SGX_EPC_CGROUP_RECLAMATIONS); + + seq_printf(m, "pages %lu\n", cur); + seq_printf(m, "direct %lu\n", dir); + seq_printf(m, "indirect %lu\n", (cur - dir)); + seq_printf(m, "reclaimed %lu\n", rec); + seq_printf(m, "reclamations %lu\n", recs); + + return 0; +} + +static ssize_t sgx_epc_stats_reset(struct kernfs_open_file *of, + char *buf, size_t nbytes, loff_t off) +{ + struct sgx_epc_cgroup *epc_cg = sgx_epc_cgroup_from_css(of_css(of)); + sgx_epc_cgroup_cnt_reset(epc_cg, SGX_EPC_CGROUP_RECLAIMED); + sgx_epc_cgroup_cnt_reset(epc_cg, SGX_EPC_CGROUP_RECLAMATIONS); + return nbytes; +} + + +static int sgx_epc_events_show(struct seq_file *m, void *v) +{ + struct sgx_epc_cgroup *epc_cg = sgx_epc_cgroup_from_css(seq_css(m)); + + unsigned long low, high, max; + low = sgx_epc_cgroup_cnt_read(epc_cg, SGX_EPC_CGROUP_LOW); + high = sgx_epc_cgroup_cnt_read(epc_cg, SGX_EPC_CGROUP_HIGH); + max = sgx_epc_cgroup_cnt_read(epc_cg, SGX_EPC_CGROUP_MAX); + + seq_printf(m, "low %lu\n", low); + seq_printf(m, "high %lu\n", high); + seq_printf(m, "max %lu\n", max); + + return 0; +} + +static ssize_t sgx_epc_events_reset(struct kernfs_open_file *of, + char *buf, size_t nbytes, loff_t off) +{ + struct sgx_epc_cgroup *epc_cg = sgx_epc_cgroup_from_css(of_css(of)); + sgx_epc_cgroup_cnt_reset(epc_cg, SGX_EPC_CGROUP_LOW); + sgx_epc_cgroup_cnt_reset(epc_cg, SGX_EPC_CGROUP_HIGH); + sgx_epc_cgroup_cnt_reset(epc_cg, SGX_EPC_CGROUP_MAX); + return nbytes; +} + + static int sgx_epc_low_show(struct seq_file *m, void *v) { struct sgx_epc_cgroup *epc_cg = sgx_epc_cgroup_from_css(seq_css(m)); @@ -729,6 +793,18 @@ static struct cftype sgx_epc_cgroup_files[] = { .read_u64 = sgx_epc_current_read, }, { + .name = "stats", + .seq_show = sgx_epc_stats_show, + .write = sgx_epc_stats_reset, + }, + { + .name = "events", + .flags = CFTYPE_NOT_ON_ROOT, + .file_offset = offsetof(struct sgx_epc_cgroup, events_file), + .seq_show = sgx_epc_events_show, + .write = sgx_epc_events_reset, + }, + { .name = "low", .flags = CFTYPE_NOT_ON_ROOT, .seq_show = sgx_epc_low_show, diff --git a/drivers/platform/x86/intel_sgx/sgx_epc_cgroup.h b/drivers/platform/x86/intel_sgx/sgx_epc_cgroup.h index 40ba7fc..ca495ab 100644 --- a/drivers/platform/x86/intel_sgx/sgx_epc_cgroup.h +++ b/drivers/platform/x86/intel_sgx/sgx_epc_cgroup.h @@ -25,6 +25,17 @@ #ifdef CONFIG_CGROUP_SGX_EPC +enum sgx_epc_cgroup_counter { + SGX_EPC_CGROUP_PAGES, + SGX_EPC_CGROUP_RECLAIMED, + SGX_EPC_CGROUP_RECLAMATIONS, + SGX_EPC_CGROUP_LOW, + SGX_EPC_CGROUP_HIGH, + SGX_EPC_CGROUP_MAX, + SGX_EPC_CGROUP_NR_COUNTERS, +}; + + struct sgx_epc_cgroup { struct cgroup_subsys_state css; @@ -36,6 +47,10 @@ struct sgx_epc_cgroup { struct sgx_epc_cgroup *reclaim_iter; struct work_struct reclaim_work; unsigned int epoch; + + atomic_long_t cnt[SGX_EPC_CGROUP_NR_COUNTERS]; + + struct cgroup_file events_file; }; struct sgx_epc_reclaim { @@ -57,6 +72,74 @@ bool sgx_epc_cgroup_is_low(struct sgx_epc_cgroup *root, struct sgx_epc_cgroup *epc_cg); bool sgx_epc_cgroup_all_in_use_are_low(struct sgx_epc_cgroup *root); + +/** + * sgx_epc_cgroup_cnt_read - read an EPC cgroup counter + * @epc_cg: the EPC cgroup + * @i: the counter index + */ +static inline unsigned long sgx_epc_cgroup_cnt_read(struct sgx_epc_cgroup *epc_cg, + enum sgx_epc_cgroup_counter i) +{ + return atomic_long_read(&epc_cg->cnt[i]); +} + +/** + * sgx_epc_cgroup_cnt_reset - reset an EPC cgroup counter + * @epc_cg: the EPC cgroup + * @i: the counter index + */ +static inline void sgx_epc_cgroup_cnt_reset(struct sgx_epc_cgroup *epc_cg, + enum sgx_epc_cgroup_counter i) +{ + atomic_long_set(&epc_cg->cnt[i], 0); +} + +/** + * sgx_epc_cgroup_cnt_add - increment an EPC cgroup counter + * @epc_cg: the EPC cgroup + * @i: the counter index + * @cnt: the number of counts to add + */ +static inline void sgx_epc_cgroup_cnt_add(struct sgx_epc_cgroup *epc_cg, + enum sgx_epc_cgroup_counter i, + unsigned long cnt) +{ + atomic_long_add(cnt, &epc_cg->cnt[i]); +} + +/** + * sgx_epc_cgroup_cnt_add - log an EPC cgroup event + * @epc_cg: the EPC cgroup + * @i: the counter index + * @cnt: the number of event counts to add + */ +static inline void sgx_epc_cgroup_event(struct sgx_epc_cgroup *epc_cg, + enum sgx_epc_cgroup_counter i, + unsigned long cnt) +{ + sgx_epc_cgroup_cnt_add(epc_cg, i, cnt); + + if (i == SGX_EPC_CGROUP_LOW || + i == SGX_EPC_CGROUP_HIGH || + i == SGX_EPC_CGROUP_MAX) + cgroup_file_notify(&epc_cg->events_file); +} + +/** + * sgx_epc_cgroup_cnt_sub - decrement an EPC cgroup counter + * @epc_cg: the EPC cgroup + * @i: the counter index + * @cnt: the number of counts to subtract + */ +static inline void sgx_epc_cgroup_cnt_sub(struct sgx_epc_cgroup *epc_cg, + enum sgx_epc_cgroup_counter i, + unsigned long cnt) +{ + atomic_long_sub(cnt, &epc_cg->cnt[i]); +} + + #else struct sgx_epc_cgroup; diff --git a/drivers/platform/x86/intel_sgx/sgx_page_cache.c b/drivers/platform/x86/intel_sgx/sgx_page_cache.c index c5e7210..426d02e 100644 --- a/drivers/platform/x86/intel_sgx/sgx_page_cache.c +++ b/drivers/platform/x86/intel_sgx/sgx_page_cache.c @@ -213,7 +213,9 @@ static void sgx_isolate_pages(struct list_head *dst, */ if (!sgx_epc_cgroup_all_in_use_are_low(root)) continue; + sgx_epc_cgroup_event(epc_cg, SGX_EPC_CGROUP_LOW, 1); } + sgx_epc_cgroup_event(epc_cg, SGX_EPC_CGROUP_RECLAIMED, 1); nr_scanned += __sgx_isolate_pages(dst, nr_to_scan - nr_scanned, &epc_cg->lru); if (nr_scanned >= nr_to_scan) { @@ -302,6 +304,13 @@ static void sgx_evict_page(struct sgx_encl_page *entry, struct sgx_encl *encl) { sgx_ewb(encl, entry); + +#ifdef CONFIG_CGROUP_SGX_EPC + if (entry->epc_page->epc_cg) + sgx_epc_cgroup_event(entry->epc_page->epc_cg, + SGX_EPC_CGROUP_RECLAIMED, 1); +#endif + sgx_free_page(entry->epc_page, encl); entry->epc_page = NULL; entry->flags &= ~SGX_ENCL_PAGE_RESERVED;