Re: drm pull for v5.3-rc1

From: Steven Price
Date: Wed Aug 07 2019 - 10:30:43 EST


On 07/08/2019 15:15, Matthew Wilcox wrote:
> On Tue, Aug 06, 2019 at 11:40:00PM -0700, Christoph Hellwig wrote:
>> On Tue, Aug 06, 2019 at 12:09:38PM -0700, Matthew Wilcox wrote:
>>> Has anyone looked at turning the interface inside-out? ie something like:
>>>
>>> struct mm_walk_state state = { .mm = mm, .start = start, .end = end, };
>>>
>>> for_each_page_range(&state, page) {
>>> ... do something with page ...
>>> }
>>>
>>> with appropriate macrology along the lines of:
>>>
>>> #define for_each_page_range(state, page) \
>>> while ((page = page_range_walk_next(state)))
>>>
>>> Then you don't need to package anything up into structs that are shared
>>> between the caller and the iterated function.
>>
>> I'm not an all that huge fan of super magic macro loops. But in this
>> case I don't see how it could even work, as we get special callbacks
>> for huge pages and holes, and people are trying to add a few more ops
>> as well.
>
> We could have bits in the mm_walk_state which indicate what things to return
> and what things to skip. We could (and probably should) also use different
> iterator names if people actually want to iterate different things. eg
> for_each_pte_range(&state, pte) as well as for_each_page_range().
>

The iterator approach could be awkward for the likes of my generic
ptdump implementation[1]. It would require an iterator which returns all
levels and allows skipping levels when required (to prevent KASAN
slowing things down too much). So something like:

start_walk_range(&state);
for_each_page_range(&state, page) {
switch(page->level) {
case PTE:
...
case PMD:
if (...)
skip_pmd(&state);
...
case HOLE:
....
...
}
}
end_walk_range(&state);

It seems a little fragile - e.g. we wouldn't (easily) get type checking
that you are actually treating a PTE as a pte_t. The state mutators like
skip_pmd() also seem a bit clumsy.

Steve

[1]
https://lore.kernel.org/lkml/20190731154603.41797-20-steven.price@xxxxxxx/