Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

firewire: core: stop using page private to store DMA mapping address

There is a long discussion about the use of private field in page
structure between Linux kernel developers.

This commit stop using page private to store DMA mapping address for
isochronous context, to prepare for mm future change.

Link: https://lore.kernel.org/r/20260110013911.19160-6-o-takashi@sakamocchi.jp
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>

+39 -40
+1 -4
drivers/firewire/core-cdev.c
··· 67 67 u64 iso_closure; 68 68 struct fw_iso_buffer buffer; 69 69 unsigned long vm_start; 70 - bool buffer_is_mapped; 71 70 72 71 struct list_head phy_receiver_link; 73 72 u64 phy_receiver_closure; ··· 1097 1098 } 1098 1099 // The DMA mapping operation is available if the buffer is already allocated by 1099 1100 // mmap(2) system call. If not, it is delegated to the system call. 1100 - if (!client->buffer_is_mapped) { 1101 + if (client->buffer.pages && !client->buffer.dma_addrs) { 1101 1102 ret = fw_iso_buffer_map_dma(&client->buffer, client->device->card, 1102 1103 iso_dma_direction(context)); 1103 1104 if (ret < 0) { ··· 1105 1106 1106 1107 return ret; 1107 1108 } 1108 - client->buffer_is_mapped = true; 1109 1109 } 1110 1110 client->iso_closure = a->closure; 1111 1111 client->iso_context = context; ··· 1835 1837 iso_dma_direction(client->iso_context)); 1836 1838 if (ret < 0) 1837 1839 goto fail; 1838 - client->buffer_is_mapped = true; 1839 1840 } 1840 1841 } 1841 1842
+25 -23
drivers/firewire/core-iso.c
··· 55 55 int fw_iso_buffer_map_dma(struct fw_iso_buffer *buffer, struct fw_card *card, 56 56 enum dma_data_direction direction) 57 57 { 58 - dma_addr_t address; 58 + dma_addr_t *dma_addrs __free(kfree) = kcalloc(buffer->page_count, sizeof(dma_addrs[0]), 59 + GFP_KERNEL); 59 60 int i; 60 61 61 - buffer->direction = direction; 62 + if (!dma_addrs) 63 + return -ENOMEM; 62 64 63 65 // Retrieve DMA mapping addresses for the pages. They are not contiguous. Maintain the cache 64 66 // coherency for the pages by hand. 65 67 for (i = 0; i < buffer->page_count; i++) { 66 68 // The dma_map_phys() with a physical address per page is available here, instead. 67 - address = dma_map_page(card->device, buffer->pages[i], 68 - 0, PAGE_SIZE, direction); 69 - if (dma_mapping_error(card->device, address)) 69 + dma_addr_t dma_addr = dma_map_page(card->device, buffer->pages[i], 0, PAGE_SIZE, 70 + direction); 71 + if (dma_mapping_error(card->device, dma_addr)) 70 72 break; 71 73 72 - set_page_private(buffer->pages[i], address); 74 + dma_addrs[i] = dma_addr; 73 75 } 74 - buffer->page_count_mapped = i; 75 - if (i < buffer->page_count) 76 + if (i < buffer->page_count) { 77 + while (i-- > 0) 78 + dma_unmap_page(card->device, dma_addrs[i], PAGE_SIZE, buffer->direction); 76 79 return -ENOMEM; 80 + } 81 + 82 + buffer->direction = direction; 83 + buffer->dma_addrs = no_free_ptr(dma_addrs); 77 84 78 85 return 0; 79 86 } ··· 105 98 void fw_iso_buffer_destroy(struct fw_iso_buffer *buffer, 106 99 struct fw_card *card) 107 100 { 108 - int i; 109 - dma_addr_t address; 110 - 111 - for (i = 0; i < buffer->page_count_mapped; i++) { 112 - address = page_private(buffer->pages[i]); 113 - dma_unmap_page(card->device, address, 114 - PAGE_SIZE, buffer->direction); 101 + if (buffer->dma_addrs) { 102 + for (int i = 0; i < buffer->page_count; ++i) { 103 + dma_addr_t dma_addr = buffer->dma_addrs[i]; 104 + dma_unmap_page(card->device, dma_addr, PAGE_SIZE, buffer->direction); 105 + } 106 + kfree(buffer->dma_addrs); 107 + buffer->dma_addrs = NULL; 115 108 } 116 109 117 110 if (buffer->pages) { ··· 121 114 } 122 115 123 116 buffer->page_count = 0; 124 - buffer->page_count_mapped = 0; 125 117 } 126 118 EXPORT_SYMBOL(fw_iso_buffer_destroy); 127 119 128 120 /* Convert DMA address to offset into virtually contiguous buffer. */ 129 121 size_t fw_iso_buffer_lookup(struct fw_iso_buffer *buffer, dma_addr_t completed) 130 122 { 131 - size_t i; 132 - dma_addr_t address; 133 - ssize_t offset; 134 - 135 - for (i = 0; i < buffer->page_count; i++) { 136 - address = page_private(buffer->pages[i]); 137 - offset = (ssize_t)completed - (ssize_t)address; 123 + for (int i = 0; i < buffer->page_count; i++) { 124 + dma_addr_t dma_addr = buffer->dma_addrs[i]; 125 + ssize_t offset = (ssize_t)completed - (ssize_t)dma_addr; 138 126 if (offset > 0 && offset <= PAGE_SIZE) 139 127 return (i << PAGE_SHIFT) + offset; 140 128 }
+12 -12
drivers/firewire/ohci.c
··· 3184 3184 struct descriptor *d, *last, *pd; 3185 3185 struct fw_iso_packet *p; 3186 3186 __le32 *header; 3187 - dma_addr_t d_bus, page_bus; 3187 + dma_addr_t d_bus; 3188 3188 u32 z, header_z, payload_z, irq; 3189 3189 u32 payload_index, payload_end_index, next_page_index; 3190 3190 int page, end_page, i, length, offset; ··· 3254 3254 min(next_page_index, payload_end_index) - payload_index; 3255 3255 pd[i].req_count = cpu_to_le16(length); 3256 3256 3257 - page_bus = page_private(buffer->pages[page]); 3258 - pd[i].data_address = cpu_to_le32(page_bus + offset); 3257 + dma_addr_t dma_addr = buffer->dma_addrs[i]; 3258 + pd[i].data_address = cpu_to_le32(dma_addr + offset); 3259 3259 3260 3260 dma_sync_single_range_for_device(ctx->context.ohci->card.device, 3261 - page_bus, offset, length, 3261 + dma_addr, offset, length, 3262 3262 DMA_TO_DEVICE); 3263 3263 3264 3264 payload_index += length; ··· 3287 3287 { 3288 3288 struct device *device = ctx->context.ohci->card.device; 3289 3289 struct descriptor *d, *pd; 3290 - dma_addr_t d_bus, page_bus; 3290 + dma_addr_t d_bus; 3291 3291 u32 z, header_z, rest; 3292 3292 int i, j, length; 3293 3293 int page, offset, packet_count, header_size, payload_per_buffer; ··· 3337 3337 pd->res_count = pd->req_count; 3338 3338 pd->transfer_status = 0; 3339 3339 3340 - page_bus = page_private(buffer->pages[page]); 3341 - pd->data_address = cpu_to_le32(page_bus + offset); 3340 + dma_addr_t dma_addr = buffer->dma_addrs[page]; 3341 + pd->data_address = cpu_to_le32(dma_addr + offset); 3342 3342 3343 - dma_sync_single_range_for_device(device, page_bus, 3343 + dma_sync_single_range_for_device(device, dma_addr, 3344 3344 offset, length, 3345 3345 DMA_FROM_DEVICE); 3346 3346 ··· 3367 3367 unsigned long payload) 3368 3368 { 3369 3369 struct descriptor *d; 3370 - dma_addr_t d_bus, page_bus; 3370 + dma_addr_t d_bus; 3371 3371 int page, offset, rest, z, i, length; 3372 3372 3373 3373 page = payload >> PAGE_SHIFT; ··· 3400 3400 d->res_count = d->req_count; 3401 3401 d->transfer_status = 0; 3402 3402 3403 - page_bus = page_private(buffer->pages[page]); 3404 - d->data_address = cpu_to_le32(page_bus + offset); 3403 + dma_addr_t dma_addr = buffer->dma_addrs[page]; 3404 + d->data_address = cpu_to_le32(dma_addr + offset); 3405 3405 3406 3406 dma_sync_single_range_for_device(ctx->context.ohci->card.device, 3407 - page_bus, offset, length, 3407 + dma_addr, offset, length, 3408 3408 DMA_FROM_DEVICE); 3409 3409 3410 3410 rest -= length;
+1 -1
include/linux/firewire.h
··· 526 526 struct fw_iso_buffer { 527 527 enum dma_data_direction direction; 528 528 struct page **pages; 529 + dma_addr_t *dma_addrs; 529 530 int page_count; 530 - int page_count_mapped; 531 531 }; 532 532 533 533 int fw_iso_buffer_init(struct fw_iso_buffer *buffer, struct fw_card *card,