Use pfn rather than struct page in ring buffer array
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 28 Apr 2015 14:55:37 +0000 (10:55 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Fri, 25 Sep 2015 17:23:20 +0000 (13:23 -0400)
First step to support permanent memory (e.g. pmem) which does not have
struct page.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
lib/ringbuffer/backend.h
lib/ringbuffer/backend_types.h
lib/ringbuffer/ring_buffer_backend.c
lib/ringbuffer/ring_buffer_mmap.c
lib/ringbuffer/ring_buffer_splice.c

index e3a0a81afb7a5b6f8bc327dce3c3847ec0a8e0b1..6f3296bc9491b2983f85ea82f2f88af2ebb6cd4c 100644 (file)
@@ -54,8 +54,8 @@ extern int __lib_ring_buffer_copy_to_user(struct lib_ring_buffer_backend *bufb,
 extern int lib_ring_buffer_read_cstr(struct lib_ring_buffer_backend *bufb,
                                     size_t offset, void *dest, size_t len);
 
-extern struct page **
-lib_ring_buffer_read_get_page(struct lib_ring_buffer_backend *bufb, size_t offset,
+extern unsigned long *
+lib_ring_buffer_read_get_pfn(struct lib_ring_buffer_backend *bufb, size_t offset,
                              void ***virt);
 
 /*
index 8c53d0754eee633e4bf958c11a82f77fbb95322e..c1d8be18323c2dc5b31003015ae69b1a81b83004 100644 (file)
@@ -28,7 +28,7 @@
 
 struct lib_ring_buffer_backend_page {
        void *virt;                     /* page virtual address (cached) */
-       struct page *page;              /* pointer to page structure */
+       unsigned long pfn;              /* page frame number */
 };
 
 struct lib_ring_buffer_backend_pages {
index 5466325f10a3b95535cf6270128254d35d656074..83a6e39b4b2df692c955c6930f04d432e4a2c88a 100644 (file)
@@ -52,7 +52,6 @@ int lib_ring_buffer_backend_allocate(const struct lib_ring_buffer_config *config
        unsigned long subbuf_size, mmap_offset = 0;
        unsigned long num_subbuf_alloc;
        struct page **pages;
-       void **virt;
        unsigned long i;
 
        num_pages = size >> PAGE_SHIFT;
@@ -71,12 +70,6 @@ int lib_ring_buffer_backend_allocate(const struct lib_ring_buffer_config *config
        if (unlikely(!pages))
                goto pages_error;
 
-       virt = kmalloc_node(ALIGN(sizeof(*virt) * num_pages,
-                                 1 << INTERNODE_CACHE_SHIFT),
-                       GFP_KERNEL, cpu_to_node(max(bufb->cpu, 0)));
-       if (unlikely(!virt))
-               goto virt_error;
-
        bufb->array = kmalloc_node(ALIGN(sizeof(*bufb->array)
                                         * num_subbuf_alloc,
                                  1 << INTERNODE_CACHE_SHIFT),
@@ -89,7 +82,6 @@ int lib_ring_buffer_backend_allocate(const struct lib_ring_buffer_config *config
                                            GFP_KERNEL | __GFP_ZERO, 0);
                if (unlikely(!pages[i]))
                        goto depopulate;
-               virt[i] = page_address(pages[i]);
        }
        bufb->num_pages_per_subbuf = num_pages_per_subbuf;
 
@@ -138,8 +130,8 @@ int lib_ring_buffer_backend_allocate(const struct lib_ring_buffer_config *config
        for (i = 0; i < num_subbuf_alloc; i++) {
                for (j = 0; j < num_pages_per_subbuf; j++) {
                        CHAN_WARN_ON(chanb, page_idx > num_pages);
-                       bufb->array[i]->p[j].virt = virt[page_idx];
-                       bufb->array[i]->p[j].page = pages[page_idx];
+                       bufb->array[i]->p[j].virt = page_address(pages[page_idx]);
+                       bufb->array[i]->p[j].pfn = page_to_pfn(pages[page_idx]);
                        page_idx++;
                }
                if (config->output == RING_BUFFER_MMAP) {
@@ -153,7 +145,6 @@ int lib_ring_buffer_backend_allocate(const struct lib_ring_buffer_config *config
         * will not fault.
         */
        wrapper_vmalloc_sync_all();
-       kfree(virt);
        kfree(pages);
        return 0;
 
@@ -168,8 +159,6 @@ depopulate:
                __free_page(pages[i]);
        kfree(bufb->array);
 array_error:
-       kfree(virt);
-virt_error:
        kfree(pages);
 pages_error:
        return -ENOMEM;
@@ -201,7 +190,7 @@ void lib_ring_buffer_backend_free(struct lib_ring_buffer_backend *bufb)
        kfree(bufb->buf_cnt);
        for (i = 0; i < num_subbuf_alloc; i++) {
                for (j = 0; j < bufb->num_pages_per_subbuf; j++)
-                       __free_page(bufb->array[i]->p[j].page);
+                       __free_page(pfn_to_page(bufb->array[i]->p[j].pfn));
                kfree(bufb->array[i]);
        }
        kfree(bufb->array);
@@ -961,15 +950,15 @@ int lib_ring_buffer_read_cstr(struct lib_ring_buffer_backend *bufb, size_t offse
 EXPORT_SYMBOL_GPL(lib_ring_buffer_read_cstr);
 
 /**
- * lib_ring_buffer_read_get_page - Get a whole page to read from
+ * lib_ring_buffer_read_get_pfn - Get a page frame number to read from
  * @bufb : buffer backend
  * @offset : offset within the buffer
  * @virt : pointer to page address (output)
  *
  * Should be protected by get_subbuf/put_subbuf.
- * Returns the pointer to the page struct pointer.
+ * Returns the pointer to the page frame number unsigned long.
  */
-struct page **lib_ring_buffer_read_get_page(struct lib_ring_buffer_backend *bufb,
+unsigned long *lib_ring_buffer_read_get_pfn(struct lib_ring_buffer_backend *bufb,
                                            size_t offset, void ***virt)
 {
        size_t index;
@@ -986,9 +975,9 @@ struct page **lib_ring_buffer_read_get_page(struct lib_ring_buffer_backend *bufb
        CHAN_WARN_ON(chanb, config->mode == RING_BUFFER_OVERWRITE
                     && subbuffer_id_is_noref(config, id));
        *virt = &rpages->p[index].virt;
-       return &rpages->p[index].page;
+       return &rpages->p[index].pfn;
 }
-EXPORT_SYMBOL_GPL(lib_ring_buffer_read_get_page);
+EXPORT_SYMBOL_GPL(lib_ring_buffer_read_get_pfn);
 
 /**
  * lib_ring_buffer_read_offset_address - get address of a buffer location
index c172fee7cfab9e2632e68adb9c617ab8e8c2fa43..2cc0dd24df0aa1749353c125c3a1f213b9cf672b 100644 (file)
@@ -38,7 +38,7 @@ static int lib_ring_buffer_fault(struct vm_area_struct *vma, struct vm_fault *vm
        struct channel *chan = buf->backend.chan;
        const struct lib_ring_buffer_config *config = &chan->backend.config;
        pgoff_t pgoff = vmf->pgoff;
-       struct page **page;
+       unsigned long *pfnp;
        void **virt;
        unsigned long offset, sb_bindex;
 
@@ -53,14 +53,14 @@ static int lib_ring_buffer_fault(struct vm_area_struct *vma, struct vm_fault *vm
                          buf->backend.chan->backend.subbuf_size))
                return VM_FAULT_SIGBUS;
        /*
-        * ring_buffer_read_get_page() gets the page in the current reader's
-        * pages.
+        * ring_buffer_read_get_pfn() gets the page frame number for the
+        * current reader's pages.
         */
-       page = lib_ring_buffer_read_get_page(&buf->backend, offset, &virt);
-       if (!*page)
+       pfnp = lib_ring_buffer_read_get_pfn(&buf->backend, offset, &virt);
+       if (!*pfnp)
                return VM_FAULT_SIGBUS;
-       get_page(*page);
-       vmf->page = *page;
+       get_page(pfn_to_page(*pfnp));
+       vmf->page = pfn_to_page(*pfnp);
 
        return 0;
 }
index bb91f45e01a303303b514814436d388ed9292c23..a1988f0bfd4adf847cfd8111931591c1e59152ff 100644 (file)
@@ -126,7 +126,8 @@ static int subbuf_splice_actor(struct file *in,
 
        for (; spd.nr_pages < nr_pages; spd.nr_pages++) {
                unsigned int this_len;
-               struct page **page, *new_page;
+               unsigned long *pfnp, new_pfn;
+               struct page *new_page;
                void **virt;
 
                if (!len)
@@ -143,11 +144,11 @@ static int subbuf_splice_actor(struct file *in,
                                            GFP_KERNEL | __GFP_ZERO, 0);
                if (!new_page)
                        break;
-
+               new_pfn = page_to_pfn(new_page);
                this_len = PAGE_SIZE - poff;
-               page = lib_ring_buffer_read_get_page(&buf->backend, roffset, &virt);
-               spd.pages[spd.nr_pages] = *page;
-               *page = new_page;
+               pfnp = lib_ring_buffer_read_get_pfn(&buf->backend, roffset, &virt);
+               spd.pages[spd.nr_pages] = pfn_to_page(*pfnp);
+               *pfnp = new_pfn;
                *virt = page_address(new_page);
                spd.partial[spd.nr_pages].offset = poff;
                spd.partial[spd.nr_pages].len = this_len;
This page took 0.030499 seconds and 4 git commands to generate.