Thread (20 messages) 20 messages, 3 authors, 2020-08-20

Re: [RFC v7 06/10] mm/damon: Implement callbacks for physical memory monitoring

From: Shakeel Butt <hidden>
Date: 2020-08-20 00:26:33
Also in: linux-mm, lkml

On Tue, Aug 18, 2020 at 12:27 AM SeongJae Park [off-list ref] wrote:
From: SeongJae Park <redacted>

This commit implements the four callbacks (->init_target_regions,
->update_target_regions, ->prepare_access_check, and ->check_accesses)
for the basic access monitoring of the physical memory address space.
By setting the callback pointers to point those, users can easily
monitor the accesses to the physical memory.

Internally, it uses the PTE Accessed bit, as similar to that of the
virtual memory support.  Also, it supports only user memory pages, as
idle page tracking also does, for the same reason.  If the monitoring
target physical memory address range contains non-user memory pages,
access check of the pages will do nothing but simply treat the pages as
not accessed.

Users who want to use other access check primitives and/or monitor the
non-user memory regions could implement and use their own callbacks.

Signed-off-by: SeongJae Park <redacted>
[snip]
+static void damon_phys_mkold(unsigned long paddr)
+{
+       struct page *page = damon_phys_get_page(PHYS_PFN(paddr));
+       struct rmap_walk_control rwc = {
+               .rmap_one = damon_page_mkold,
+               .anon_lock = page_lock_anon_vma_read,
+       };
+       bool need_lock;
+
+       if (!page)
+               return;
+
+       if (!page_mapped(page) || !page_rmapping(page))
+               return;
I don't think you want to skip the unmapped pages. The point of
physical address space monitoring was to include the monitoring of
unmapped pages, so, skipping them invalidates the underlying
motivation.
+
+       need_lock = !PageAnon(page) || PageKsm(page);
+       if (need_lock && !trylock_page(page))
+               return;
+
+       rmap_walk(page, &rwc);
+
+       if (need_lock)
+               unlock_page(page);
+       put_page(page);
+}
+
[snip]
+
+static bool damon_phys_young(unsigned long paddr, unsigned long *page_sz)
+{
+       struct page *page = damon_phys_get_page(PHYS_PFN(paddr));
+       struct damon_phys_access_chk_result result = {
+               .page_sz = PAGE_SIZE,
+               .accessed = false,
+       };
+       struct rmap_walk_control rwc = {
+               .arg = &result,
+               .rmap_one = damon_page_accessed,
+               .anon_lock = page_lock_anon_vma_read,
+       };
+       bool need_lock;
+
+       if (!page)
+               return false;
+
+       if (!page_mapped(page) || !page_rmapping(page))
+               return false;
Same here.
+
+       need_lock = !PageAnon(page) || PageKsm(page);
+       if (need_lock && !trylock_page(page))
+               return false;
+
+       rmap_walk(page, &rwc);
+
+       if (need_lock)
+               unlock_page(page);
+       put_page(page);
+
+       *page_sz = result.page_sz;
+       return result.accessed;
+}
+
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help