As an aside, why should discard work in this case even without step 4?
Wouldn't setting "read-only" imply you don't want the memory to change
out from under you? I guess I'm not clear on the semantics: how do memory
protection bits map to madvise actions like this?
They generally don't affect MADV_DONTNEED behavior. The only documented
(man page) reason for EPERM in the man page is related to MADV_HWPOISON.