Commit 837596a61ba8f9bb53bb7aa27d17328ff9b2bcd5

Authored by Clemens Ladisch
Committed by Stefan Richter
1 parent a1f805e5e7

firewire: ohci: avoid reallocation of AR buffers

Freeing an AR buffer page just to allocate a new page immediately
afterwards is not only a pointless effort but also dangerous because
the allocation can fail, which would result in an oops later.

Split ar_context_add_page() into two functions so that we can reuse
the old page directly.

Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Tested-by: Maxim Levitsky <maximlevitsky@gmail.com>
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>

Showing 1 changed file with 16 additions and 12 deletions Side-by-side Diff

drivers/firewire/ohci.c
... ... @@ -577,17 +577,11 @@
577 577 return ret;
578 578 }
579 579  
580   -static int ar_context_add_page(struct ar_context *ctx)
  580 +static void ar_context_link_page(struct ar_context *ctx,
  581 + struct ar_buffer *ab, dma_addr_t ab_bus)
581 582 {
582   - struct device *dev = ctx->ohci->card.device;
583   - struct ar_buffer *ab;
584   - dma_addr_t uninitialized_var(ab_bus);
585 583 size_t offset;
586 584  
587   - ab = dma_alloc_coherent(dev, PAGE_SIZE, &ab_bus, GFP_ATOMIC);
588   - if (ab == NULL)
589   - return -ENOMEM;
590   -
591 585 ab->next = NULL;
592 586 memset(&ab->descriptor, 0, sizeof(ab->descriptor));
593 587 ab->descriptor.control = cpu_to_le16(DESCRIPTOR_INPUT_MORE |
594 588  
... ... @@ -606,7 +600,20 @@
606 600  
607 601 reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE);
608 602 flush_writes(ctx->ohci);
  603 +}
609 604  
  605 +static int ar_context_add_page(struct ar_context *ctx)
  606 +{
  607 + struct device *dev = ctx->ohci->card.device;
  608 + struct ar_buffer *ab;
  609 + dma_addr_t uninitialized_var(ab_bus);
  610 +
  611 + ab = dma_alloc_coherent(dev, PAGE_SIZE, &ab_bus, GFP_ATOMIC);
  612 + if (ab == NULL)
  613 + return -ENOMEM;
  614 +
  615 + ar_context_link_page(ctx, ab, ab_bus);
  616 +
610 617 return 0;
611 618 }
612 619  
... ... @@ -730,7 +737,6 @@
730 737 static void ar_context_tasklet(unsigned long data)
731 738 {
732 739 struct ar_context *ctx = (struct ar_context *)data;
733   - struct fw_ohci *ohci = ctx->ohci;
734 740 struct ar_buffer *ab;
735 741 struct descriptor *d;
736 742 void *buffer, *end;
... ... @@ -799,9 +805,7 @@
799 805 ctx->current_buffer = ab;
800 806 ctx->pointer = end;
801 807  
802   - dma_free_coherent(ohci->card.device, PAGE_SIZE,
803   - start, start_bus);
804   - ar_context_add_page(ctx);
  808 + ar_context_link_page(ctx, start, start_bus);
805 809 } else {
806 810 ctx->pointer = start + PAGE_SIZE;
807 811 }