On Thu, Nov 17, 2011 at 21:52, Keith Packard <keithp at keithp.com> wrote: > On Wed, 28 Sep 2011 11:57:24 +0200, Daniel Vetter <daniel.vetter at ffwll.ch> wrote: > >> + ? ? char __user *end = uaddr + size - 1; > > ... > >> + ? ? if (ret == 0) { >> + ? ? ? ? ? ? if (((unsigned long)uaddr & PAGE_MASK) != >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ((unsigned long)end & PAGE_MASK)) >> + ? ? ? ? ? ? ? ? ? ? ret = __put_user(0, end); >> + ? ? } > > This is wrong -- if size == PAGE_SIZE, then we'll be doing an extra > write at 'end' every time (and, I imagine that's a common case). We want to prefault the last byte if the pfn of the last prefault address doesn't match the pfn of the last byte of the userspace address range. Only happens when userspace hands in badly aligned address, not every time. I've rechecked and I think the code actually does what I want it to do. > And, you mentioned a 'better' fix? Chris was despised at the lack of beauty of the code and I agree. Due to the ppgtt trip to Poland I haven't gotten around to do it actually. Actually I've just noticed that this is might be the old pwrite/pread series (mail here still sucks). The new one fixes up the prefault helpers in pagemap.h (instead of reinventing the wheel for i915.ko), but they have the same issue of profound ugliness. -Daniel -- Daniel Vetter daniel.vetter at ffwll.ch - +41 (0) 79 365 57 48 - http://blog.ffwll.ch