Comment 20 for bug 1742316

Revision history for this message
Kai-Heng Feng (kaihengfeng) wrote :

The problem is that the commit you bisected implicitly use GFP_HIGHMEM mask. A later commit, tries to alleviate the issue by not setting GFP_HIGHMEM when GFP_DMA or GFP_DMA32 is set,

commit 704b862f9efd6d4c87a8d0a344dda19bda9c6b69
Author: Laura Abbott <email address hidden>
Date: Fri Aug 18 15:16:27 2017 -0700

    mm/vmalloc.c: don't unconditonally use __GFP_HIGHMEM

So add GFP_DMA32 or GFP_DMA should solve the issue, but it doesn't,
diff --git a/drivers/media/common/saa7146/saa7146_core.c b/drivers/media/common/saa7146/saa7146_core.c
index 9f7c5b0a6b45..69f127067aa1 100644
--- a/drivers/media/common/saa7146/saa7146_core.c
+++ b/drivers/media/common/saa7146/saa7146_core.c
@@ -152,7 +152,8 @@ static struct scatterlist* vmalloc_to_sg(unsigned char *virt, int nr_pages)
        struct page *pg;
        int i;

- sglist = kcalloc(nr_pages, sizeof(struct scatterlist), GFP_KERNEL);
+ sglist = __vmalloc(nr_pages * sizeof(struct scatterlist),
+ GFP_KERNEL | GFP_DMA | __GFP_ZERO, PAGE_KERNEL);
        if (NULL == sglist)
                return NULL;
        sg_init_table(sglist, nr_pages);
@@ -166,7 +167,7 @@ static struct scatterlist* vmalloc_to_sg(unsigned char *virt, int nr_pages)
        return sglist;

  err:
- kfree(sglist);
+ vfree(sglist);
        return NULL;
 }

@@ -203,7 +204,7 @@ void *saa7146_vmalloc_build_pgtable(struct pci_dev *pci, long length, struct saa
 err_free_pgtable:
        saa7146_pgtable_free(pci, pt);
 err_free_slist:
- kfree(pt->slist);
+ vfree(pt->slist);
        pt->slist = NULL;
 err_free_mem:
        vfree(mem);
@@ -215,7 +216,7 @@ void saa7146_vfree_destroy_pgtable(struct pci_dev *pci, void *mem, struct saa714
 {
        pci_unmap_sg(pci, pt->slist, pt->nents, PCI_DMA_FROMDEVICE);
        saa7146_pgtable_free(pci, pt);
- kfree(pt->slist);
+ vfree(pt->slist);
        pt->slist = NULL;
        vfree(mem);
 }

I'll send a mail to ask the patch author, stay tuned.