media: atomisp: Fix alloc_pages_bulk() failed errors

Systems with the atomisp ISP do not have a lot of memory for modern
standards, so these are often under memory pressure and alloc_pages_bulk()
does not try very hard to free pages before returning an amount of pages
which is less then requested. This leads to streaming from the camera
often failing with a "alloc_pages_bulk() failed" error.

vmalloc() also uses alloc_pages_bulk(), but falls back to allocating one
page at a time when that fails.

Do the same in alloc_private_pages() to avoid these errors.

While at it also drop the weird custom GFP flags and just use GFP_KERNEL
and drop the dev_err() as alloc_pages() already complaints loudly if
it fails itself.

Closes: https://github.com/jfwells/linux-asus-t100ta/issues/4
Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
This commit is contained in:
Hans de Goede 2026-03-10 13:18:26 +01:00 committed by Sakari Ailus
parent 4e8156bd95
commit 0a41dd4aab

View File

@ -620,14 +620,23 @@ static void free_private_bo_pages(struct hmm_buffer_object *bo)
/*Allocate pages which will be used only by ISP*/
static int alloc_private_pages(struct hmm_buffer_object *bo)
{
const gfp_t gfp = __GFP_NOWARN | __GFP_RECLAIM | __GFP_FS;
unsigned int nr_allocated = 0;
struct page *page;
int ret;
ret = alloc_pages_bulk(gfp, bo->pgnr, bo->pages);
if (ret != bo->pgnr) {
free_pages_bulk_array(ret, bo->pages);
dev_err(atomisp_dev, "alloc_pages_bulk() failed\n");
return -ENOMEM;
nr_allocated = alloc_pages_bulk(GFP_KERNEL, bo->pgnr, bo->pages);
/*
* alloc_pages_bulk() does not try very hard to get pages under memory
* pressure. If necessary fall back to alloc_page().
*/
while (nr_allocated < bo->pgnr) {
page = alloc_pages(GFP_KERNEL, 0);
if (!page) {
free_pages_bulk_array(nr_allocated, bo->pages);
return -ENOMEM;
}
bo->pages[nr_allocated] = page;
nr_allocated++;
}
ret = set_pages_array_uc(bo->pages, bo->pgnr);