[PATCH] mm: incorrect VM_FAULT_OOM returns from drivers
Some drivers are returning OOM when it is not in response to a memory shortage. Signed-off-by: Nick Piggin <npiggin@suse.de> Cc: Dave Airlie <airlied@linux.ie> Cc: Jaroslav Kysela <perex@suse.cz> Cc: Takashi Iwai <tiwai@suse.de> Cc: Greg KH <greg@kroah.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
f2a2a7108a
commit
cd54e7e543
@ -147,14 +147,14 @@ static __inline__ struct page *drm_do_vm_shm_nopage(struct vm_area_struct *vma,
|
|||||||
if (address > vma->vm_end)
|
if (address > vma->vm_end)
|
||||||
return NOPAGE_SIGBUS; /* Disallow mremap */
|
return NOPAGE_SIGBUS; /* Disallow mremap */
|
||||||
if (!map)
|
if (!map)
|
||||||
return NOPAGE_OOM; /* Nothing allocated */
|
return NOPAGE_SIGBUS; /* Nothing allocated */
|
||||||
|
|
||||||
offset = address - vma->vm_start;
|
offset = address - vma->vm_start;
|
||||||
i = (unsigned long)map->handle + offset;
|
i = (unsigned long)map->handle + offset;
|
||||||
page = (map->type == _DRM_CONSISTENT) ?
|
page = (map->type == _DRM_CONSISTENT) ?
|
||||||
virt_to_page((void *)i) : vmalloc_to_page((void *)i);
|
virt_to_page((void *)i) : vmalloc_to_page((void *)i);
|
||||||
if (!page)
|
if (!page)
|
||||||
return NOPAGE_OOM;
|
return NOPAGE_SIGBUS;
|
||||||
get_page(page);
|
get_page(page);
|
||||||
|
|
||||||
DRM_DEBUG("shm_nopage 0x%lx\n", address);
|
DRM_DEBUG("shm_nopage 0x%lx\n", address);
|
||||||
@ -272,7 +272,7 @@ static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma,
|
|||||||
if (address > vma->vm_end)
|
if (address > vma->vm_end)
|
||||||
return NOPAGE_SIGBUS; /* Disallow mremap */
|
return NOPAGE_SIGBUS; /* Disallow mremap */
|
||||||
if (!dma->pagelist)
|
if (!dma->pagelist)
|
||||||
return NOPAGE_OOM; /* Nothing allocated */
|
return NOPAGE_SIGBUS; /* Nothing allocated */
|
||||||
|
|
||||||
offset = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */
|
offset = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */
|
||||||
page_nr = offset >> PAGE_SHIFT;
|
page_nr = offset >> PAGE_SHIFT;
|
||||||
@ -310,7 +310,7 @@ static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma,
|
|||||||
if (address > vma->vm_end)
|
if (address > vma->vm_end)
|
||||||
return NOPAGE_SIGBUS; /* Disallow mremap */
|
return NOPAGE_SIGBUS; /* Disallow mremap */
|
||||||
if (!entry->pagelist)
|
if (!entry->pagelist)
|
||||||
return NOPAGE_OOM; /* Nothing allocated */
|
return NOPAGE_SIGBUS; /* Nothing allocated */
|
||||||
|
|
||||||
offset = address - vma->vm_start;
|
offset = address - vma->vm_start;
|
||||||
map_offset = map->offset - (unsigned long)dev->sg->virtual;
|
map_offset = map->offset - (unsigned long)dev->sg->virtual;
|
||||||
|
@ -3027,7 +3027,7 @@ static struct page * snd_pcm_mmap_status_nopage(struct vm_area_struct *area,
|
|||||||
struct page * page;
|
struct page * page;
|
||||||
|
|
||||||
if (substream == NULL)
|
if (substream == NULL)
|
||||||
return NOPAGE_OOM;
|
return NOPAGE_SIGBUS;
|
||||||
runtime = substream->runtime;
|
runtime = substream->runtime;
|
||||||
page = virt_to_page(runtime->status);
|
page = virt_to_page(runtime->status);
|
||||||
get_page(page);
|
get_page(page);
|
||||||
@ -3070,7 +3070,7 @@ static struct page * snd_pcm_mmap_control_nopage(struct vm_area_struct *area,
|
|||||||
struct page * page;
|
struct page * page;
|
||||||
|
|
||||||
if (substream == NULL)
|
if (substream == NULL)
|
||||||
return NOPAGE_OOM;
|
return NOPAGE_SIGBUS;
|
||||||
runtime = substream->runtime;
|
runtime = substream->runtime;
|
||||||
page = virt_to_page(runtime->control);
|
page = virt_to_page(runtime->control);
|
||||||
get_page(page);
|
get_page(page);
|
||||||
@ -3131,18 +3131,18 @@ static struct page *snd_pcm_mmap_data_nopage(struct vm_area_struct *area,
|
|||||||
size_t dma_bytes;
|
size_t dma_bytes;
|
||||||
|
|
||||||
if (substream == NULL)
|
if (substream == NULL)
|
||||||
return NOPAGE_OOM;
|
return NOPAGE_SIGBUS;
|
||||||
runtime = substream->runtime;
|
runtime = substream->runtime;
|
||||||
offset = area->vm_pgoff << PAGE_SHIFT;
|
offset = area->vm_pgoff << PAGE_SHIFT;
|
||||||
offset += address - area->vm_start;
|
offset += address - area->vm_start;
|
||||||
snd_assert((offset % PAGE_SIZE) == 0, return NOPAGE_OOM);
|
snd_assert((offset % PAGE_SIZE) == 0, return NOPAGE_SIGBUS);
|
||||||
dma_bytes = PAGE_ALIGN(runtime->dma_bytes);
|
dma_bytes = PAGE_ALIGN(runtime->dma_bytes);
|
||||||
if (offset > dma_bytes - PAGE_SIZE)
|
if (offset > dma_bytes - PAGE_SIZE)
|
||||||
return NOPAGE_SIGBUS;
|
return NOPAGE_SIGBUS;
|
||||||
if (substream->ops->page) {
|
if (substream->ops->page) {
|
||||||
page = substream->ops->page(substream, offset);
|
page = substream->ops->page(substream, offset);
|
||||||
if (! page)
|
if (! page)
|
||||||
return NOPAGE_OOM;
|
return NOPAGE_OOM; /* XXX: is this really due to OOM? */
|
||||||
} else {
|
} else {
|
||||||
vaddr = runtime->dma_area + offset;
|
vaddr = runtime->dma_area + offset;
|
||||||
page = virt_to_page(vaddr);
|
page = virt_to_page(vaddr);
|
||||||
|
@ -2120,8 +2120,8 @@ static struct page * via_mm_nopage (struct vm_area_struct * vma,
|
|||||||
return NOPAGE_SIGBUS; /* Disallow mremap */
|
return NOPAGE_SIGBUS; /* Disallow mremap */
|
||||||
}
|
}
|
||||||
if (!card) {
|
if (!card) {
|
||||||
DPRINTK ("EXIT, returning NOPAGE_OOM\n");
|
DPRINTK ("EXIT, returning NOPAGE_SIGBUS\n");
|
||||||
return NOPAGE_OOM; /* Nothing allocated */
|
return NOPAGE_SIGBUS; /* Nothing allocated */
|
||||||
}
|
}
|
||||||
|
|
||||||
pgoff = vma->vm_pgoff + ((address - vma->vm_start) >> PAGE_SHIFT);
|
pgoff = vma->vm_pgoff + ((address - vma->vm_start) >> PAGE_SHIFT);
|
||||||
|
@ -48,7 +48,7 @@ static struct page * snd_us428ctls_vm_nopage(struct vm_area_struct *area, unsign
|
|||||||
|
|
||||||
offset = area->vm_pgoff << PAGE_SHIFT;
|
offset = area->vm_pgoff << PAGE_SHIFT;
|
||||||
offset += address - area->vm_start;
|
offset += address - area->vm_start;
|
||||||
snd_assert((offset % PAGE_SIZE) == 0, return NOPAGE_OOM);
|
snd_assert((offset % PAGE_SIZE) == 0, return NOPAGE_SIGBUS);
|
||||||
vaddr = (char*)((struct usX2Ydev *)area->vm_private_data)->us428ctls_sharedmem + offset;
|
vaddr = (char*)((struct usX2Ydev *)area->vm_private_data)->us428ctls_sharedmem + offset;
|
||||||
page = virt_to_page(vaddr);
|
page = virt_to_page(vaddr);
|
||||||
get_page(page);
|
get_page(page);
|
||||||
|
Loading…
Reference in New Issue
Block a user