]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
firewire: core: code refactoring with cleanup function for isoc pages
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Sat, 10 Jan 2026 01:39:06 +0000 (10:39 +0900)
committerTakashi Sakamoto <o-takashi@sakamocchi.jp>
Mon, 12 Jan 2026 02:49:37 +0000 (11:49 +0900)
This commit refactors the implementation to allocate pages for isochronous
DMA contexts with cleanup function.

Link: https://lore.kernel.org/r/20260110013911.19160-4-o-takashi@sakamocchi.jp
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
drivers/firewire/core-iso.c

index a67493862c856455e24dace87a0abf8b9a90ff28..e678ffba5de245ef2bdca1bc9f23dd18e5986780 100644 (file)
 
 int fw_iso_buffer_alloc(struct fw_iso_buffer *buffer, int page_count)
 {
+       struct page **page_array __free(kfree) = kcalloc(page_count, sizeof(page_array[0]), GFP_KERNEL);
        int i;
 
-       buffer->page_count = 0;
-       buffer->page_count_mapped = 0;
-       buffer->pages = kmalloc_array(page_count, sizeof(buffer->pages[0]),
-                                     GFP_KERNEL);
-       if (buffer->pages == NULL)
+       if (!page_array)
                return -ENOMEM;
 
-       for (i = 0; i < page_count; i++) {
-               buffer->pages[i] = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO);
-               if (buffer->pages[i] == NULL)
+       for (i = 0; i < page_count; ++i) {
+               struct page *page = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO);
+
+               if (!page)
                        break;
+               page_array[i] = page;
        }
-       buffer->page_count = i;
+
        if (i < page_count) {
-               fw_iso_buffer_destroy(buffer, NULL);
+               while (i-- > 0)
+                       __free_page(page_array[i]);
                return -ENOMEM;
        }
 
+       buffer->page_count = page_count;
+       buffer->pages = no_free_ptr(page_array);
+
        return 0;
 }
 
@@ -104,11 +107,14 @@ void fw_iso_buffer_destroy(struct fw_iso_buffer *buffer,
                dma_unmap_page(card->device, address,
                               PAGE_SIZE, buffer->direction);
        }
-       for (i = 0; i < buffer->page_count; i++)
-               __free_page(buffer->pages[i]);
 
-       kfree(buffer->pages);
-       buffer->pages = NULL;
+       if (buffer->pages) {
+               for (int i = 0; i < buffer->page_count; ++i)
+                       __free_page(buffer->pages[i]);
+               kfree(buffer->pages);
+               buffer->pages = NULL;
+       }
+
        buffer->page_count = 0;
        buffer->page_count_mapped = 0;
 }