|
@@ -1176,7 +1176,15 @@ static inline unsigned interleave_nid(struct mempolicy *pol,
|
|
if (vma) {
|
|
if (vma) {
|
|
unsigned long off;
|
|
unsigned long off;
|
|
|
|
|
|
- off = vma->vm_pgoff;
|
|
|
|
|
|
+ /*
|
|
|
|
+ * for small pages, there is no difference between
|
|
|
|
+ * shift and PAGE_SHIFT, so the bit-shift is safe.
|
|
|
|
+ * for huge pages, since vm_pgoff is in units of small
|
|
|
|
+ * pages, we need to shift off the always 0 bits to get
|
|
|
|
+ * a useful offset.
|
|
|
|
+ */
|
|
|
|
+ BUG_ON(shift < PAGE_SHIFT);
|
|
|
|
+ off = vma->vm_pgoff >> (shift - PAGE_SHIFT);
|
|
off += (addr - vma->vm_start) >> shift;
|
|
off += (addr - vma->vm_start) >> shift;
|
|
return offset_il_node(pol, vma, off);
|
|
return offset_il_node(pol, vma, off);
|
|
} else
|
|
} else
|