[RFC PATCH 11/20] x86/sgx: Add option to ignore age of page during EPC reclaim

From: Kristen Carlson Accardi
Date: Thu Sep 22 2022 - 13:13:14 EST


From: Sean Christopherson <sean.j.christopherson@xxxxxxxxx>

Add a flag to sgx_reclaim_pages() to instruct it to ignore the age of
page, i.e. reclaim the page even if it's young. The EPC cgroup will use
the flag to enforce its limits by draining the reclaimable lists before
resorting to other measures, e.g. forcefully reclaimable "unreclaimable"
pages by killing enclaves.

Signed-off-by: Sean Christopherson <sean.j.christopherson@xxxxxxxxx>
Signed-off-by: Kristen Carlson Accardi <kristen@xxxxxxxxxxxxxxx>
Cc: Sean Christopherson <seanjc@xxxxxxxxxx>
---
arch/x86/kernel/cpu/sgx/main.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/cpu/sgx/main.c b/arch/x86/kernel/cpu/sgx/main.c
index fc5aed813834..98531f6fb448 100644
--- a/arch/x86/kernel/cpu/sgx/main.c
+++ b/arch/x86/kernel/cpu/sgx/main.c
@@ -278,6 +278,7 @@ static void sgx_reclaimer_write(struct sgx_epc_page *epc_page,
/**
* sgx_reclaim_pages() - Reclaim EPC pages from the consumers
* @nr_to_scan: Number of EPC pages to scan for reclaim
+ * @ignore_age: Reclaim a page even if it is young
*
* Take a fixed number of pages from the head of the active page pool and
* reclaim them to the enclave's private shmem files. Skip the pages, which have
@@ -293,7 +294,7 @@ static void sgx_reclaimer_write(struct sgx_epc_page *epc_page,
*
* Return: number of EPC pages reclaimed
*/
-static int sgx_reclaim_pages(int nr_to_scan)
+static int sgx_reclaim_pages(int nr_to_scan, bool ignore_age)
{
struct sgx_backing backing[SGX_MAX_NR_TO_RECLAIM];
struct sgx_encl_page *encl_page;
@@ -334,7 +335,8 @@ static int sgx_reclaim_pages(int nr_to_scan)
list_for_each_entry_safe(epc_page, tmp, &iso, list) {
encl_page = epc_page->owner;

- if (i == SGX_MAX_NR_TO_RECLAIM || !sgx_reclaimer_age(epc_page))
+ if (i == SGX_MAX_NR_TO_RECLAIM ||
+ (!ignore_age && !sgx_reclaimer_age(epc_page)))
goto skip;

page_index = PFN_DOWN(encl_page->desc - encl_page->encl->base);
@@ -392,7 +394,7 @@ static bool sgx_should_reclaim(unsigned long watermark)
void sgx_reclaim_direct(void)
{
if (sgx_should_reclaim(SGX_NR_LOW_PAGES))
- sgx_reclaim_pages(SGX_NR_TO_SCAN);
+ sgx_reclaim_pages(SGX_NR_TO_SCAN, false);
}

static int ksgxd(void *p)
@@ -418,7 +420,7 @@ static int ksgxd(void *p)
sgx_should_reclaim(SGX_NR_HIGH_PAGES));

if (sgx_should_reclaim(SGX_NR_HIGH_PAGES))
- sgx_reclaim_pages(SGX_NR_TO_SCAN);
+ sgx_reclaim_pages(SGX_NR_TO_SCAN, false);
}

return 0;
@@ -589,7 +591,7 @@ struct sgx_epc_page *sgx_alloc_epc_page(void *owner, bool reclaim)
break;
}

- sgx_reclaim_pages(SGX_NR_TO_SCAN);
+ sgx_reclaim_pages(SGX_NR_TO_SCAN, false);
}

if (sgx_should_reclaim(SGX_NR_LOW_PAGES))
--
2.37.3