Since start is a static variable, it must be updated this way. The intention
here is to shorten the loop in later runs - since kernel page table entries
never go away, this is possible. Possibly just using the insync array would
be sufficient, but when I first coded this I wanted to avoid as much
overhead as was possible.
Does that matter? If pgd_list is empty, then it's in sync by definition. Why does it need special-casing?No, it isn't. Note the setting to NULL of page, which after the loop getsspin_lock_irqsave(&pgd_lock, flags);This seems a bit warty. If the list is empty, then won't the list_for_each_entry() just fall through? Presumably this only applies to boot, since pgd_list won't be empty on a running system with usermode processes. Is there a correctness issue here, or is it just a micro-optimisation?
+ if (unlikely(list_empty(&pgd_list))) {
+ spin_unlock_irqrestore(&pgd_lock, flags);
+ return;
+ }
tested for. list_for_each_entry() would never yield a NULL page, even
if the list is empty.
Yes, certainly. But it would result in all insync bits set, which would be
wrong - only non-empty page directory entries can be in sync.
Could you add a comment?This is a replacement of the BUG_ON() that an earlier patch from youlist_for_each_entry(page, &pgd_list, lru) {What condition is this testing for?
if (!vmalloc_sync_one(page_address(page),
- address))
+ address)) {
+ BUG_ON(list_first_entry(&pgd_list,
+ struct page,
+ lru) != page);
removed: Failure of vmalloc_sync_one() must happen on the first
entry or never, and this is what is being checked for here.
Sure, though there was none originally, and the intention seemed
quite clear to me.