diff options
author | Andrea Arcangeli <aarcange@redhat.com> | 2021-11-23 12:54:02 -0500 |
---|---|---|
committer | Andrea Arcangeli <aarcange@redhat.com> | 2023-11-11 22:03:38 -0500 |
commit | 09e766700bb046f7da3363a77ac8470f7d105c34 (patch) | |
tree | 90b8ce1a919805b1b8661c112c82d4df5d0a8b26 | |
parent | 5a61c9041a4485eb9607ff32e383a65346661b87 (diff) | |
download | aa-09e766700bb046f7da3363a77ac8470f7d105c34.tar.gz |
randprotect: KSM: add batch random generator helper
can_write_protect() returns a random boolean generated from a 50%
Bernoulli distribution (p = 1/2). This is an helper required later.
Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>
-rw-r--r-- | mm/ksm.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/mm/ksm.c b/mm/ksm.c index d8090082acf943..f82cea52f09143 100644 --- a/mm/ksm.c +++ b/mm/ksm.c @@ -38,6 +38,7 @@ #include <linux/freezer.h> #include <linux/oom.h> #include <linux/numa.h> +#include <linux/random.h> #include <asm/tlbflush.h> #include "internal.h" @@ -124,12 +125,19 @@ struct mm_slot { struct mm_struct *mm; }; +#define NR_RANDOM_LONGS 8 +struct random_batch { + unsigned long bits[NR_RANDOM_LONGS]; + unsigned int bit; +}; + /** * struct ksm_scan - cursor for scanning * @mm_slot: the current mm_slot we are scanning * @address: the next address inside that to be scanned * @rmap_list: link to the next rmap to be scanned in the rmap_list * @seqnr: count of completed full scans (needed when removing unstable node) + * @random_bytes: random payload batching * * There is only the one ksm_scan instance of this cursor structure. */ @@ -138,6 +146,7 @@ struct ksm_scan { unsigned long address; struct rmap_item **rmap_list; unsigned long seqnr; + struct random_batch random_batch; }; /** @@ -301,6 +310,23 @@ static DEFINE_SPINLOCK(ksm_mmlist_lock); sizeof(struct __struct), __alignof__(struct __struct),\ (__flags), NULL) +/* + * Decide if to write protect pages whose payload didn't change over + * the last KSM scans (according to checksum) based on a Bernoulli + * distribution with p = 1/2. + */ +static bool can_write_protect(void) +{ + struct random_batch *random = &ksm_scan.random_batch; + if (!random->bit) { + get_random_bytes(&random->bits, + sizeof(random->bits)); + random->bit = sizeof(random->bits) * 8; + } + random->bit--; + return test_bit(random->bit, random->bits); +} + static int __init ksm_slab_init(void) { rmap_item_cache = KSM_KMEM_CACHE(rmap_item, 0); |