Re: [RFC][PATCH 4/5 v4] dma-buf: heaps: Add CMA heap to dmabuf heaps

2019-05-16 Thread John Stultz
On Tue, May 14, 2019 at 3:40 AM Xiaqing (A)  wrote:
>
>
>
> On 2019/5/14 2:37, John Stultz wrote:
> > This adds a CMA heap, which allows userspace to allocate
> > a dma-buf of contiguous memory out of a CMA region.
> >
> > This code is an evolution of the Android ION implementation, so
> > thanks to its original author and maintainters:
> >Benjamin Gaignard, Laura Abbott, and others!
> >
> > Cc: Laura Abbott 
> > Cc: Benjamin Gaignard 
> > Cc: Sumit Semwal 
> > Cc: Liam Mark 
> > Cc: Pratik Patel 
> > Cc: Brian Starkey 
> > Cc: Vincent Donnefort 
> > Cc: Sudipto Paul 
> > Cc: Andrew F. Davis 
> > Cc: Xu YiPing 
> > Cc: "Chenfeng (puck)" 
> > Cc: butao 
> > Cc: "Xiaqing (A)" 
> > Cc: Yudongbin 
> > Cc: Christoph Hellwig 
> > Cc: Chenbo Feng 
> > Cc: Alistair Strachan 
> > Cc: dri-devel@lists.freedesktop.org
> > Signed-off-by: John Stultz 
> > ---
> > v2:
> > * Switch allocate to return dmabuf fd
> > * Simplify init code
> > * Checkpatch fixups
> > v3:
> > * Switch to inline function for to_cma_heap()
> > * Minor cleanups suggested by Brian
> > * Fold in new registration style from Andrew
> > * Folded in changes from Andrew to use simplified page list
> >from the heap helpers
> > * Use the fd_flags when creating dmabuf fd (Suggested by
> >Benjamin)
> > * Use precalculated pagecount (Suggested by Andrew)
> > ---
> >   drivers/dma-buf/heaps/Kconfig|   8 ++
> >   drivers/dma-buf/heaps/Makefile   |   1 +
> >   drivers/dma-buf/heaps/cma_heap.c | 169 +++
> >   3 files changed, 178 insertions(+)
> >   create mode 100644 drivers/dma-buf/heaps/cma_heap.c
> >
> > diff --git a/drivers/dma-buf/heaps/Kconfig b/drivers/dma-buf/heaps/Kconfig
> > index 205052744169..a5eef06c4226 100644
> > --- a/drivers/dma-buf/heaps/Kconfig
> > +++ b/drivers/dma-buf/heaps/Kconfig
> > @@ -4,3 +4,11 @@ config DMABUF_HEAPS_SYSTEM
> >   help
> > Choose this option to enable the system dmabuf heap. The system heap
> > is backed by pages from the buddy allocator. If in doubt, say Y.
> > +
> > +config DMABUF_HEAPS_CMA
> > + bool "DMA-BUF CMA Heap"
> > + depends on DMABUF_HEAPS && DMA_CMA
> > + help
> > +   Choose this option to enable dma-buf CMA heap. This heap is backed
> > +   by the Contiguous Memory Allocator (CMA). If your system has these
> > +   regions, you should say Y here.
> > diff --git a/drivers/dma-buf/heaps/Makefile b/drivers/dma-buf/heaps/Makefile
> > index d1808eca2581..6e54cdec3da0 100644
> > --- a/drivers/dma-buf/heaps/Makefile
> > +++ b/drivers/dma-buf/heaps/Makefile
> > @@ -1,3 +1,4 @@
> >   # SPDX-License-Identifier: GPL-2.0
> >   obj-y   += heap-helpers.o
> >   obj-$(CONFIG_DMABUF_HEAPS_SYSTEM)   += system_heap.o
> > +obj-$(CONFIG_DMABUF_HEAPS_CMA)   += cma_heap.o
> > diff --git a/drivers/dma-buf/heaps/cma_heap.c 
> > b/drivers/dma-buf/heaps/cma_heap.c
> > new file mode 100644
> > index ..3d0ffbbd0a34
> > --- /dev/null
> > +++ b/drivers/dma-buf/heaps/cma_heap.c
> > @@ -0,0 +1,169 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * DMABUF CMA heap exporter
> > + *
> > + * Copyright (C) 2012, 2019 Linaro Ltd.
> > + * Author:  for ST-Ericsson.
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include "heap-helpers.h"
> > +
> > +struct cma_heap {
> > + struct dma_heap *heap;
> > + struct cma *cma;
> > +};
> > +
> > +static void cma_heap_free(struct heap_helper_buffer *buffer)
> > +{
> > + struct cma_heap *cma_heap = 
> > dma_heap_get_data(buffer->heap_buffer.heap);
> > + unsigned long nr_pages = buffer->pagecount;
> > + struct page *pages = buffer->priv_virt;
> > +
> > + /* free page list */
> > + kfree(buffer->pages);
> > + /* release memory */
> > + cma_release(cma_heap->cma, pages, nr_pages);
> > + kfree(buffer);
> > +}
> > +
> > +/* dmabuf heap CMA operations functions */
> > +static int cma_heap_allocate(struct dma_heap *heap,
> > + unsigned long len,
> > + unsigned long fd_flags,
> > + unsigned long heap_flags)
> > +{
> > + struct cma_heap *cma_heap = dma_heap_get_data(heap);
> > + struct heap_helper_buffer *helper_buffer;
> > + struct page *pages;
> > + size_t size = PAGE_ALIGN(len);
> > + unsigned long nr_pages = size >> PAGE_SHIFT;
> > + unsigned long align = get_order(size);
> > + DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
> > + struct dma_buf *dmabuf;
> > + int ret = -ENOMEM;
> > + pgoff_t pg;
> > +
> > + if (align > CONFIG_CMA_ALIGNMENT)
> > + align = CONFIG_CMA_ALIGNMENT;
> > +
> > + helper_buffer = kzalloc(sizeof(*helper_buffer), GFP_KERNEL);
> > + if (!helper_buffer)
> > + return -ENOMEM;
> > +
> > + INIT_HEAP_HELPER_BUFFER(helper_buffer, 

Re: [RFC][PATCH 4/5 v4] dma-buf: heaps: Add CMA heap to dmabuf heaps

2019-05-14 Thread Benjamin Gaignard
Le mar. 14 mai 2019 à 12:40, Xiaqing (A)  a écrit :
>
>
>
> On 2019/5/14 2:37, John Stultz wrote:
> > This adds a CMA heap, which allows userspace to allocate
> > a dma-buf of contiguous memory out of a CMA region.
> >
> > This code is an evolution of the Android ION implementation, so
> > thanks to its original author and maintainters:
> >Benjamin Gaignard, Laura Abbott, and others!
> >
> > Cc: Laura Abbott 
> > Cc: Benjamin Gaignard 
> > Cc: Sumit Semwal 
> > Cc: Liam Mark 
> > Cc: Pratik Patel 
> > Cc: Brian Starkey 
> > Cc: Vincent Donnefort 
> > Cc: Sudipto Paul 
> > Cc: Andrew F. Davis 
> > Cc: Xu YiPing 
> > Cc: "Chenfeng (puck)" 
> > Cc: butao 
> > Cc: "Xiaqing (A)" 
> > Cc: Yudongbin 
> > Cc: Christoph Hellwig 
> > Cc: Chenbo Feng 
> > Cc: Alistair Strachan 
> > Cc: dri-devel@lists.freedesktop.org
> > Signed-off-by: John Stultz 
> > ---
> > v2:
> > * Switch allocate to return dmabuf fd
> > * Simplify init code
> > * Checkpatch fixups
> > v3:
> > * Switch to inline function for to_cma_heap()
> > * Minor cleanups suggested by Brian
> > * Fold in new registration style from Andrew
> > * Folded in changes from Andrew to use simplified page list
> >from the heap helpers
> > * Use the fd_flags when creating dmabuf fd (Suggested by
> >Benjamin)
> > * Use precalculated pagecount (Suggested by Andrew)
> > ---
> >   drivers/dma-buf/heaps/Kconfig|   8 ++
> >   drivers/dma-buf/heaps/Makefile   |   1 +
> >   drivers/dma-buf/heaps/cma_heap.c | 169 +++
> >   3 files changed, 178 insertions(+)
> >   create mode 100644 drivers/dma-buf/heaps/cma_heap.c
> >
> > diff --git a/drivers/dma-buf/heaps/Kconfig b/drivers/dma-buf/heaps/Kconfig
> > index 205052744169..a5eef06c4226 100644
> > --- a/drivers/dma-buf/heaps/Kconfig
> > +++ b/drivers/dma-buf/heaps/Kconfig
> > @@ -4,3 +4,11 @@ config DMABUF_HEAPS_SYSTEM
> >   help
> > Choose this option to enable the system dmabuf heap. The system heap
> > is backed by pages from the buddy allocator. If in doubt, say Y.
> > +
> > +config DMABUF_HEAPS_CMA
> > + bool "DMA-BUF CMA Heap"
> > + depends on DMABUF_HEAPS && DMA_CMA
> > + help
> > +   Choose this option to enable dma-buf CMA heap. This heap is backed
> > +   by the Contiguous Memory Allocator (CMA). If your system has these
> > +   regions, you should say Y here.
> > diff --git a/drivers/dma-buf/heaps/Makefile b/drivers/dma-buf/heaps/Makefile
> > index d1808eca2581..6e54cdec3da0 100644
> > --- a/drivers/dma-buf/heaps/Makefile
> > +++ b/drivers/dma-buf/heaps/Makefile
> > @@ -1,3 +1,4 @@
> >   # SPDX-License-Identifier: GPL-2.0
> >   obj-y   += heap-helpers.o
> >   obj-$(CONFIG_DMABUF_HEAPS_SYSTEM)   += system_heap.o
> > +obj-$(CONFIG_DMABUF_HEAPS_CMA)   += cma_heap.o
> > diff --git a/drivers/dma-buf/heaps/cma_heap.c 
> > b/drivers/dma-buf/heaps/cma_heap.c
> > new file mode 100644
> > index ..3d0ffbbd0a34
> > --- /dev/null
> > +++ b/drivers/dma-buf/heaps/cma_heap.c
> > @@ -0,0 +1,169 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * DMABUF CMA heap exporter
> > + *
> > + * Copyright (C) 2012, 2019 Linaro Ltd.
> > + * Author:  for ST-Ericsson.
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include "heap-helpers.h"
> > +
> > +struct cma_heap {
> > + struct dma_heap *heap;
> > + struct cma *cma;
> > +};
> > +
> > +static void cma_heap_free(struct heap_helper_buffer *buffer)
> > +{
> > + struct cma_heap *cma_heap = 
> > dma_heap_get_data(buffer->heap_buffer.heap);
> > + unsigned long nr_pages = buffer->pagecount;
> > + struct page *pages = buffer->priv_virt;
> > +
> > + /* free page list */
> > + kfree(buffer->pages);
> > + /* release memory */
> > + cma_release(cma_heap->cma, pages, nr_pages);
> > + kfree(buffer);
> > +}
> > +
> > +/* dmabuf heap CMA operations functions */
> > +static int cma_heap_allocate(struct dma_heap *heap,
> > + unsigned long len,
> > + unsigned long fd_flags,
> > + unsigned long heap_flags)
> > +{
> > + struct cma_heap *cma_heap = dma_heap_get_data(heap);
> > + struct heap_helper_buffer *helper_buffer;
> > + struct page *pages;
> > + size_t size = PAGE_ALIGN(len);
> > + unsigned long nr_pages = size >> PAGE_SHIFT;
> > + unsigned long align = get_order(size);
> > + DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
> > + struct dma_buf *dmabuf;
> > + int ret = -ENOMEM;
> > + pgoff_t pg;
> > +
> > + if (align > CONFIG_CMA_ALIGNMENT)
> > + align = CONFIG_CMA_ALIGNMENT;
> > +
> > + helper_buffer = kzalloc(sizeof(*helper_buffer), GFP_KERNEL);
> > + if (!helper_buffer)
> > + return -ENOMEM;
> > +
> > + INIT_HEAP_HELPER_BUFFER(helper_buffer, 

Re: [RFC][PATCH 4/5 v4] dma-buf: heaps: Add CMA heap to dmabuf heaps

2019-05-14 Thread Xiaqing (A)




On 2019/5/14 2:37, John Stultz wrote:

This adds a CMA heap, which allows userspace to allocate
a dma-buf of contiguous memory out of a CMA region.

This code is an evolution of the Android ION implementation, so
thanks to its original author and maintainters:
   Benjamin Gaignard, Laura Abbott, and others!

Cc: Laura Abbott 
Cc: Benjamin Gaignard 
Cc: Sumit Semwal 
Cc: Liam Mark 
Cc: Pratik Patel 
Cc: Brian Starkey 
Cc: Vincent Donnefort 
Cc: Sudipto Paul 
Cc: Andrew F. Davis 
Cc: Xu YiPing 
Cc: "Chenfeng (puck)" 
Cc: butao 
Cc: "Xiaqing (A)" 
Cc: Yudongbin 
Cc: Christoph Hellwig 
Cc: Chenbo Feng 
Cc: Alistair Strachan 
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: John Stultz 
---
v2:
* Switch allocate to return dmabuf fd
* Simplify init code
* Checkpatch fixups
v3:
* Switch to inline function for to_cma_heap()
* Minor cleanups suggested by Brian
* Fold in new registration style from Andrew
* Folded in changes from Andrew to use simplified page list
   from the heap helpers
* Use the fd_flags when creating dmabuf fd (Suggested by
   Benjamin)
* Use precalculated pagecount (Suggested by Andrew)
---
  drivers/dma-buf/heaps/Kconfig|   8 ++
  drivers/dma-buf/heaps/Makefile   |   1 +
  drivers/dma-buf/heaps/cma_heap.c | 169 +++
  3 files changed, 178 insertions(+)
  create mode 100644 drivers/dma-buf/heaps/cma_heap.c

diff --git a/drivers/dma-buf/heaps/Kconfig b/drivers/dma-buf/heaps/Kconfig
index 205052744169..a5eef06c4226 100644
--- a/drivers/dma-buf/heaps/Kconfig
+++ b/drivers/dma-buf/heaps/Kconfig
@@ -4,3 +4,11 @@ config DMABUF_HEAPS_SYSTEM
help
  Choose this option to enable the system dmabuf heap. The system heap
  is backed by pages from the buddy allocator. If in doubt, say Y.
+
+config DMABUF_HEAPS_CMA
+   bool "DMA-BUF CMA Heap"
+   depends on DMABUF_HEAPS && DMA_CMA
+   help
+ Choose this option to enable dma-buf CMA heap. This heap is backed
+ by the Contiguous Memory Allocator (CMA). If your system has these
+ regions, you should say Y here.
diff --git a/drivers/dma-buf/heaps/Makefile b/drivers/dma-buf/heaps/Makefile
index d1808eca2581..6e54cdec3da0 100644
--- a/drivers/dma-buf/heaps/Makefile
+++ b/drivers/dma-buf/heaps/Makefile
@@ -1,3 +1,4 @@
  # SPDX-License-Identifier: GPL-2.0
  obj-y += heap-helpers.o
  obj-$(CONFIG_DMABUF_HEAPS_SYSTEM) += system_heap.o
+obj-$(CONFIG_DMABUF_HEAPS_CMA) += cma_heap.o
diff --git a/drivers/dma-buf/heaps/cma_heap.c b/drivers/dma-buf/heaps/cma_heap.c
new file mode 100644
index ..3d0ffbbd0a34
--- /dev/null
+++ b/drivers/dma-buf/heaps/cma_heap.c
@@ -0,0 +1,169 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DMABUF CMA heap exporter
+ *
+ * Copyright (C) 2012, 2019 Linaro Ltd.
+ * Author:  for ST-Ericsson.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "heap-helpers.h"
+
+struct cma_heap {
+   struct dma_heap *heap;
+   struct cma *cma;
+};
+
+static void cma_heap_free(struct heap_helper_buffer *buffer)
+{
+   struct cma_heap *cma_heap = dma_heap_get_data(buffer->heap_buffer.heap);
+   unsigned long nr_pages = buffer->pagecount;
+   struct page *pages = buffer->priv_virt;
+
+   /* free page list */
+   kfree(buffer->pages);
+   /* release memory */
+   cma_release(cma_heap->cma, pages, nr_pages);
+   kfree(buffer);
+}
+
+/* dmabuf heap CMA operations functions */
+static int cma_heap_allocate(struct dma_heap *heap,
+   unsigned long len,
+   unsigned long fd_flags,
+   unsigned long heap_flags)
+{
+   struct cma_heap *cma_heap = dma_heap_get_data(heap);
+   struct heap_helper_buffer *helper_buffer;
+   struct page *pages;
+   size_t size = PAGE_ALIGN(len);
+   unsigned long nr_pages = size >> PAGE_SHIFT;
+   unsigned long align = get_order(size);
+   DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
+   struct dma_buf *dmabuf;
+   int ret = -ENOMEM;
+   pgoff_t pg;
+
+   if (align > CONFIG_CMA_ALIGNMENT)
+   align = CONFIG_CMA_ALIGNMENT;
+
+   helper_buffer = kzalloc(sizeof(*helper_buffer), GFP_KERNEL);
+   if (!helper_buffer)
+   return -ENOMEM;
+
+   INIT_HEAP_HELPER_BUFFER(helper_buffer, cma_heap_free);
+   helper_buffer->heap_buffer.flags = heap_flags;
+   helper_buffer->heap_buffer.heap = heap;
+   helper_buffer->heap_buffer.size = len;
+
+   pages = cma_alloc(cma_heap->cma, nr_pages, align, false);
+   if (!pages)
+   goto free_buf;
+
+   if (PageHighMem(pages)) {
+   unsigned long nr_clear_pages = nr_pages;
+   struct page *page = pages;
+
+   while (nr_clear_pages > 0) {
+   void *vaddr = kmap_atomic(page);
+
+   memset(vaddr, 0, 

[RFC][PATCH 4/5 v4] dma-buf: heaps: Add CMA heap to dmabuf heaps

2019-05-13 Thread John Stultz
This adds a CMA heap, which allows userspace to allocate
a dma-buf of contiguous memory out of a CMA region.

This code is an evolution of the Android ION implementation, so
thanks to its original author and maintainters:
  Benjamin Gaignard, Laura Abbott, and others!

Cc: Laura Abbott 
Cc: Benjamin Gaignard 
Cc: Sumit Semwal 
Cc: Liam Mark 
Cc: Pratik Patel 
Cc: Brian Starkey 
Cc: Vincent Donnefort 
Cc: Sudipto Paul 
Cc: Andrew F. Davis 
Cc: Xu YiPing 
Cc: "Chenfeng (puck)" 
Cc: butao 
Cc: "Xiaqing (A)" 
Cc: Yudongbin 
Cc: Christoph Hellwig 
Cc: Chenbo Feng 
Cc: Alistair Strachan 
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: John Stultz 
---
v2:
* Switch allocate to return dmabuf fd
* Simplify init code
* Checkpatch fixups
v3:
* Switch to inline function for to_cma_heap()
* Minor cleanups suggested by Brian
* Fold in new registration style from Andrew
* Folded in changes from Andrew to use simplified page list
  from the heap helpers
* Use the fd_flags when creating dmabuf fd (Suggested by
  Benjamin)
* Use precalculated pagecount (Suggested by Andrew)
---
 drivers/dma-buf/heaps/Kconfig|   8 ++
 drivers/dma-buf/heaps/Makefile   |   1 +
 drivers/dma-buf/heaps/cma_heap.c | 169 +++
 3 files changed, 178 insertions(+)
 create mode 100644 drivers/dma-buf/heaps/cma_heap.c

diff --git a/drivers/dma-buf/heaps/Kconfig b/drivers/dma-buf/heaps/Kconfig
index 205052744169..a5eef06c4226 100644
--- a/drivers/dma-buf/heaps/Kconfig
+++ b/drivers/dma-buf/heaps/Kconfig
@@ -4,3 +4,11 @@ config DMABUF_HEAPS_SYSTEM
help
  Choose this option to enable the system dmabuf heap. The system heap
  is backed by pages from the buddy allocator. If in doubt, say Y.
+
+config DMABUF_HEAPS_CMA
+   bool "DMA-BUF CMA Heap"
+   depends on DMABUF_HEAPS && DMA_CMA
+   help
+ Choose this option to enable dma-buf CMA heap. This heap is backed
+ by the Contiguous Memory Allocator (CMA). If your system has these
+ regions, you should say Y here.
diff --git a/drivers/dma-buf/heaps/Makefile b/drivers/dma-buf/heaps/Makefile
index d1808eca2581..6e54cdec3da0 100644
--- a/drivers/dma-buf/heaps/Makefile
+++ b/drivers/dma-buf/heaps/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-y  += heap-helpers.o
 obj-$(CONFIG_DMABUF_HEAPS_SYSTEM)  += system_heap.o
+obj-$(CONFIG_DMABUF_HEAPS_CMA) += cma_heap.o
diff --git a/drivers/dma-buf/heaps/cma_heap.c b/drivers/dma-buf/heaps/cma_heap.c
new file mode 100644
index ..3d0ffbbd0a34
--- /dev/null
+++ b/drivers/dma-buf/heaps/cma_heap.c
@@ -0,0 +1,169 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DMABUF CMA heap exporter
+ *
+ * Copyright (C) 2012, 2019 Linaro Ltd.
+ * Author:  for ST-Ericsson.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "heap-helpers.h"
+
+struct cma_heap {
+   struct dma_heap *heap;
+   struct cma *cma;
+};
+
+static void cma_heap_free(struct heap_helper_buffer *buffer)
+{
+   struct cma_heap *cma_heap = dma_heap_get_data(buffer->heap_buffer.heap);
+   unsigned long nr_pages = buffer->pagecount;
+   struct page *pages = buffer->priv_virt;
+
+   /* free page list */
+   kfree(buffer->pages);
+   /* release memory */
+   cma_release(cma_heap->cma, pages, nr_pages);
+   kfree(buffer);
+}
+
+/* dmabuf heap CMA operations functions */
+static int cma_heap_allocate(struct dma_heap *heap,
+   unsigned long len,
+   unsigned long fd_flags,
+   unsigned long heap_flags)
+{
+   struct cma_heap *cma_heap = dma_heap_get_data(heap);
+   struct heap_helper_buffer *helper_buffer;
+   struct page *pages;
+   size_t size = PAGE_ALIGN(len);
+   unsigned long nr_pages = size >> PAGE_SHIFT;
+   unsigned long align = get_order(size);
+   DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
+   struct dma_buf *dmabuf;
+   int ret = -ENOMEM;
+   pgoff_t pg;
+
+   if (align > CONFIG_CMA_ALIGNMENT)
+   align = CONFIG_CMA_ALIGNMENT;
+
+   helper_buffer = kzalloc(sizeof(*helper_buffer), GFP_KERNEL);
+   if (!helper_buffer)
+   return -ENOMEM;
+
+   INIT_HEAP_HELPER_BUFFER(helper_buffer, cma_heap_free);
+   helper_buffer->heap_buffer.flags = heap_flags;
+   helper_buffer->heap_buffer.heap = heap;
+   helper_buffer->heap_buffer.size = len;
+
+   pages = cma_alloc(cma_heap->cma, nr_pages, align, false);
+   if (!pages)
+   goto free_buf;
+
+   if (PageHighMem(pages)) {
+   unsigned long nr_clear_pages = nr_pages;
+   struct page *page = pages;
+
+   while (nr_clear_pages > 0) {
+   void *vaddr = kmap_atomic(page);
+
+   memset(vaddr, 0, PAGE_SIZE);
+   kunmap_atomic(vaddr);