Commit aae86e8adb3bbf5256eebe76500cf7254365753c

Authored by Michal Nazarewicz
Committed by Greg Kroah-Hartman
1 parent ddb495d4d8

USB: f_mass_storage: dynamic buffers for better alignment

"Static" buffers in fsg_buffhd structure (ie. fields which are arrays
rather then pointers to dynamically allocated memory) are not aligned
to any "big" power of two which may lead to poor DMA performance
(copying "by hand" of head or tail) or no DMA at all even if otherwise
hardware supports it.

Therefore, this patch makes mass storage function use kmalloc()ed
buffers which are (because of their size) page aligned (which should
be enough for any hardware).

Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com>
Cc: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

Showing 1 changed file with 18 additions and 5 deletions Side-by-side Diff

drivers/usb/gadget/f_mass_storage.c
... ... @@ -302,7 +302,6 @@
302 302  
303 303  
304 304 #define FSG_NO_INTR_EP 1
305   -#define FSG_BUFFHD_STATIC_BUFFER 1
306 305 #define FSG_NO_DEVICE_STRINGS 1
307 306 #define FSG_NO_OTG 1
308 307 #define FSG_NO_INTR_EP 1
309 308  
310 309  
... ... @@ -2762,13 +2761,19 @@
2762 2761  
2763 2762  
2764 2763 /* Data buffers cyclic list */
2765   - /* Buffers in buffhds are static -- no need for additional
2766   - * allocation. */
2767 2764 bh = common->buffhds;
2768   - i = FSG_NUM_BUFFERS - 1;
  2765 + i = FSG_NUM_BUFFERS;
  2766 + goto buffhds_first_it;
2769 2767 do {
2770 2768 bh->next = bh + 1;
2771   - } while (++bh, --i);
  2769 + ++bh;
  2770 +buffhds_first_it:
  2771 + bh->buf = kmalloc(FSG_BUFLEN, GFP_KERNEL);
  2772 + if (unlikely(!bh->buf)) {
  2773 + rc = -ENOMEM;
  2774 + goto error_release;
  2775 + }
  2776 + } while (--i);
2772 2777 bh->next = common->buffhds;
2773 2778  
2774 2779  
... ... @@ -2871,6 +2876,7 @@
2871 2876 container_of(ref, struct fsg_common, ref);
2872 2877 unsigned i = common->nluns;
2873 2878 struct fsg_lun *lun = common->luns;
  2879 + struct fsg_buffhd *bh;
2874 2880  
2875 2881 /* If the thread isn't already dead, tell it to exit now */
2876 2882 if (common->state != FSG_STATE_TERMINATED) {
... ... @@ -2892,6 +2898,13 @@
2892 2898 }
2893 2899  
2894 2900 kfree(common->luns);
  2901 +
  2902 + i = FSG_NUM_BUFFERS;
  2903 + bh = common->buffhds;
  2904 + do {
  2905 + kfree(bh->buf);
  2906 + } while (++bh, --i);
  2907 +
2895 2908 if (common->free_storage_on_release)
2896 2909 kfree(common);
2897 2910 }