From: Sasha Levin Date: Wed, 7 Jun 2023 01:39:46 +0000 (-0400) Subject: Fixes for 5.15 X-Git-Tag: v4.14.317~42 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f75777b32580b2c495fe11b492a4f77f82a0d3c2;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.15 Signed-off-by: Sasha Levin --- diff --git a/queue-5.15/block-fix-revalidate-performance-regression.patch b/queue-5.15/block-fix-revalidate-performance-regression.patch new file mode 100644 index 00000000000..fa73864a463 --- /dev/null +++ b/queue-5.15/block-fix-revalidate-performance-regression.patch @@ -0,0 +1,63 @@ +From 4c8caef3c9e2e4c90db8697ce768ecb05261942f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 May 2023 16:32:37 +0900 +Subject: block: fix revalidate performance regression + +From: Damien Le Moal + +[ Upstream commit 47fe1c3064c6bc1bfa3c032ff78e603e5dd6e5bc ] + +The scsi driver function sd_read_block_characteristics() always calls +disk_set_zoned() to a disk zoned model correctly, in case the device +model changed. This is done even for regular disks to set the zoned +model to BLK_ZONED_NONE and free any zone related resources if the drive +previously was zoned. + +This behavior significantly impact the time it takes to revalidate disks +on a large system as the call to disk_clear_zone_settings() done from +disk_set_zoned() for the BLK_ZONED_NONE case results in the device +request queued to be frozen, even if there are no zone resources to +free. + +Avoid this overhead for non-zoned devices by not calling +disk_clear_zone_settings() in disk_set_zoned() if the device model +was already set to BLK_ZONED_NONE, which is always the case for regular +devices. + +Reported by: Brian Bunker + +Fixes: 508aebb80527 ("block: introduce blk_queue_clear_zone_settings()") +Cc: stable@vger.kernel.org +Signed-off-by: Damien Le Moal +Reviewed-by: Ming Lei +Link: https://lore.kernel.org/r/20230529073237.1339862-1-dlemoal@kernel.org +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + block/blk-settings.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/block/blk-settings.c b/block/blk-settings.c +index 8b84b4f126966..b2dfbfd08cbbd 100644 +--- a/block/blk-settings.c ++++ b/block/blk-settings.c +@@ -875,6 +875,7 @@ static bool disk_has_partitions(struct gendisk *disk) + void blk_queue_set_zoned(struct gendisk *disk, enum blk_zoned_model model) + { + struct request_queue *q = disk->queue; ++ unsigned int old_model = q->limits.zoned; + + switch (model) { + case BLK_ZONED_HM: +@@ -912,7 +913,7 @@ void blk_queue_set_zoned(struct gendisk *disk, enum blk_zoned_model model) + */ + blk_queue_zone_write_granularity(q, + queue_logical_block_size(q)); +- } else { ++ } else if (old_model != BLK_ZONED_NONE) { + disk_clear_zone_settings(disk); + } + } +-- +2.39.2 + diff --git a/queue-5.15/block-pass-a-gendisk-to-blk_queue_clear_zone_setting.patch b/queue-5.15/block-pass-a-gendisk-to-blk_queue_clear_zone_setting.patch new file mode 100644 index 00000000000..4c6a0cc947c --- /dev/null +++ b/queue-5.15/block-pass-a-gendisk-to-blk_queue_clear_zone_setting.patch @@ -0,0 +1,75 @@ +From 1011c6b47b0dfafc6fa92f182e76b1b713a14fee Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Jul 2022 09:03:41 +0200 +Subject: block: pass a gendisk to blk_queue_clear_zone_settings + +From: Christoph Hellwig + +[ Upstream commit b3c72f8138b5f967a9fa527af84b35018897aba3 ] + +Switch to a gendisk based API in preparation for moving all zone related +fields from the request_queue to the gendisk. + +Signed-off-by: Christoph Hellwig +Reviewed-by: Chaitanya Kulkarni +Reviewed-by: Damien Le Moal +Reviewed-by: Johannes Thumshirn +Link: https://lore.kernel.org/r/20220706070350.1703384-8-hch@lst.de +Signed-off-by: Jens Axboe +Stable-dep-of: 47fe1c3064c6 ("block: fix revalidate performance regression") +Signed-off-by: Sasha Levin +--- + block/blk-settings.c | 2 +- + block/blk-zoned.c | 4 +++- + block/blk.h | 4 ++-- + 3 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/block/blk-settings.c b/block/blk-settings.c +index b880c70e22e4e..8b84b4f126966 100644 +--- a/block/blk-settings.c ++++ b/block/blk-settings.c +@@ -913,7 +913,7 @@ void blk_queue_set_zoned(struct gendisk *disk, enum blk_zoned_model model) + blk_queue_zone_write_granularity(q, + queue_logical_block_size(q)); + } else { +- blk_queue_clear_zone_settings(q); ++ disk_clear_zone_settings(disk); + } + } + EXPORT_SYMBOL_GPL(blk_queue_set_zoned); +diff --git a/block/blk-zoned.c b/block/blk-zoned.c +index 774ecc598bee2..2629ec5d977b4 100644 +--- a/block/blk-zoned.c ++++ b/block/blk-zoned.c +@@ -630,8 +630,10 @@ int blk_revalidate_disk_zones(struct gendisk *disk, + } + EXPORT_SYMBOL_GPL(blk_revalidate_disk_zones); + +-void blk_queue_clear_zone_settings(struct request_queue *q) ++void disk_clear_zone_settings(struct gendisk *disk) + { ++ struct request_queue *q = disk->queue; ++ + blk_mq_freeze_queue(q); + + blk_queue_free_zone_bitmaps(q); +diff --git a/block/blk.h b/block/blk.h +index aab72194d2266..336bdb35466ee 100644 +--- a/block/blk.h ++++ b/block/blk.h +@@ -343,10 +343,10 @@ struct bio *blk_next_bio(struct bio *bio, unsigned int nr_pages, gfp_t gfp); + + #ifdef CONFIG_BLK_DEV_ZONED + void blk_queue_free_zone_bitmaps(struct request_queue *q); +-void blk_queue_clear_zone_settings(struct request_queue *q); ++void disk_clear_zone_settings(struct gendisk *disk); + #else + static inline void blk_queue_free_zone_bitmaps(struct request_queue *q) {} +-static inline void blk_queue_clear_zone_settings(struct request_queue *q) {} ++static inline void disk_clear_zone_settings(struct gendisk *disk) {} + #endif + + int blk_alloc_ext_minor(void); +-- +2.39.2 + diff --git a/queue-5.15/series b/queue-5.15/series index 03f25e833ef..f54f5206740 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -127,3 +127,7 @@ tty-serial-fsl_lpuart-use-uartctrl_txinv-to-send-break-instead-of-uartctrl_sbk.p btrfs-fix-csum_tree_block-page-iteration-to-avoid-tripping-on-werror-array-bounds.patch powerpc-iommu-limit-number-of-tces-to-512-for-h_stuff_tce-hcall.patch iommu-amd-fix-domain-flush-size-when-syncing-iotlb.patch +usb-cdns3-allocate-tx-fifo-size-according-to-composi.patch +usb-cdns3-fix-ncm-gadget-rx-speed-20x-slow-than-expe.patch +block-pass-a-gendisk-to-blk_queue_clear_zone_setting.patch +block-fix-revalidate-performance-regression.patch diff --git a/queue-5.15/usb-cdns3-allocate-tx-fifo-size-according-to-composi.patch b/queue-5.15/usb-cdns3-allocate-tx-fifo-size-according-to-composi.patch new file mode 100644 index 00000000000..9298c744275 --- /dev/null +++ b/queue-5.15/usb-cdns3-allocate-tx-fifo-size-according-to-composi.patch @@ -0,0 +1,192 @@ +From 751a1dc41ef88fec04fc5566402bb984391891b4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 May 2022 11:40:55 -0500 +Subject: usb: cdns3: allocate TX FIFO size according to composite EP number + +From: Frank Li + +[ Upstream commit dce49449e04ff150838a31386ee65917beb9ebb5 ] + +Some devices have USB compositions which may require multiple endpoints. +To get better performance, need bigger CDNS3_EP_BUF_SIZE. + +But bigger CDNS3_EP_BUF_SIZE may exceed total hardware FIFO size when +multiple endpoints. + +By introducing the check_config() callback, calculate CDNS3_EP_BUF_SIZE. + +Move CDNS3_EP_BUF_SIZE into cnds3_device: ep_buf_size +Combine CDNS3_EP_ISO_SS_BURST and CDNS3_EP_ISO_HS_MULT into +cnds3_device:ep_iso_burst + +Using a simple algorithm to calculate ep_buf_size. +ep_buf_size = ep_iso_burst = (onchip_buffers - 2k) / (number of IN EP + +1). + +Test at 8qxp: + + Gadget ep_buf_size + + RNDIS: 5 + RNDIS+ACM: 3 + Mass Storage + NCM + ACM 2 + +Previous CDNS3_EP_BUF_SIZE is 4, RNDIS + ACM will be failure because +exceed FIFO memory. + +Acked-by: Peter Chen +Signed-off-by: Frank Li +Link: https://lore.kernel.org/r/20220509164055.1815081-1-Frank.Li@nxp.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: dbe678f6192f ("usb: cdns3: fix NCM gadget RX speed 20x slow than expection at iMX8QM") +Signed-off-by: Sasha Levin +--- + drivers/usb/cdns3/cdns3-gadget.c | 47 +++++++++++++++++++++++++++++--- + drivers/usb/cdns3/cdns3-gadget.h | 9 ++++-- + 2 files changed, 49 insertions(+), 7 deletions(-) + +diff --git a/drivers/usb/cdns3/cdns3-gadget.c b/drivers/usb/cdns3/cdns3-gadget.c +index 924c2793c7327..ccfaebca6faa7 100644 +--- a/drivers/usb/cdns3/cdns3-gadget.c ++++ b/drivers/usb/cdns3/cdns3-gadget.c +@@ -2040,7 +2040,7 @@ int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable) + u8 mult = 0; + int ret; + +- buffering = CDNS3_EP_BUF_SIZE - 1; ++ buffering = priv_dev->ep_buf_size - 1; + + cdns3_configure_dmult(priv_dev, priv_ep); + +@@ -2059,7 +2059,7 @@ int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable) + break; + default: + ep_cfg = EP_CFG_EPTYPE(USB_ENDPOINT_XFER_ISOC); +- mult = CDNS3_EP_ISO_HS_MULT - 1; ++ mult = priv_dev->ep_iso_burst - 1; + buffering = mult + 1; + } + +@@ -2075,14 +2075,14 @@ int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable) + mult = 0; + max_packet_size = 1024; + if (priv_ep->type == USB_ENDPOINT_XFER_ISOC) { +- maxburst = CDNS3_EP_ISO_SS_BURST - 1; ++ maxburst = priv_dev->ep_iso_burst - 1; + buffering = (mult + 1) * + (maxburst + 1); + + if (priv_ep->interval > 1) + buffering++; + } else { +- maxburst = CDNS3_EP_BUF_SIZE - 1; ++ maxburst = priv_dev->ep_buf_size - 1; + } + break; + default: +@@ -2097,6 +2097,10 @@ int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable) + else + priv_ep->trb_burst_size = 16; + ++ mult = min_t(u8, mult, EP_CFG_MULT_MAX); ++ buffering = min_t(u8, buffering, EP_CFG_BUFFERING_MAX); ++ maxburst = min_t(u8, maxburst, EP_CFG_MAXBURST_MAX); ++ + /* onchip buffer is only allocated before configuration */ + if (!priv_dev->hw_configured_flag) { + ret = cdns3_ep_onchip_buffer_reserve(priv_dev, buffering + 1, +@@ -2982,6 +2986,40 @@ static int cdns3_gadget_udc_stop(struct usb_gadget *gadget) + return 0; + } + ++/** ++ * cdns3_gadget_check_config - ensure cdns3 can support the USB configuration ++ * @gadget: pointer to the USB gadget ++ * ++ * Used to record the maximum number of endpoints being used in a USB composite ++ * device. (across all configurations) This is to be used in the calculation ++ * of the TXFIFO sizes when resizing internal memory for individual endpoints. ++ * It will help ensured that the resizing logic reserves enough space for at ++ * least one max packet. ++ */ ++static int cdns3_gadget_check_config(struct usb_gadget *gadget) ++{ ++ struct cdns3_device *priv_dev = gadget_to_cdns3_device(gadget); ++ struct usb_ep *ep; ++ int n_in = 0; ++ int total; ++ ++ list_for_each_entry(ep, &gadget->ep_list, ep_list) { ++ if (ep->claimed && (ep->address & USB_DIR_IN)) ++ n_in++; ++ } ++ ++ /* 2KB are reserved for EP0, 1KB for out*/ ++ total = 2 + n_in + 1; ++ ++ if (total > priv_dev->onchip_buffers) ++ return -ENOMEM; ++ ++ priv_dev->ep_buf_size = priv_dev->ep_iso_burst = ++ (priv_dev->onchip_buffers - 2) / (n_in + 1); ++ ++ return 0; ++} ++ + static const struct usb_gadget_ops cdns3_gadget_ops = { + .get_frame = cdns3_gadget_get_frame, + .wakeup = cdns3_gadget_wakeup, +@@ -2990,6 +3028,7 @@ static const struct usb_gadget_ops cdns3_gadget_ops = { + .udc_start = cdns3_gadget_udc_start, + .udc_stop = cdns3_gadget_udc_stop, + .match_ep = cdns3_gadget_match_ep, ++ .check_config = cdns3_gadget_check_config, + }; + + static void cdns3_free_all_eps(struct cdns3_device *priv_dev) +diff --git a/drivers/usb/cdns3/cdns3-gadget.h b/drivers/usb/cdns3/cdns3-gadget.h +index c5660f2c4293f..fbe4a8e3aa897 100644 +--- a/drivers/usb/cdns3/cdns3-gadget.h ++++ b/drivers/usb/cdns3/cdns3-gadget.h +@@ -562,15 +562,18 @@ struct cdns3_usb_regs { + /* Max burst size (used only in SS mode). */ + #define EP_CFG_MAXBURST_MASK GENMASK(11, 8) + #define EP_CFG_MAXBURST(p) (((p) << 8) & EP_CFG_MAXBURST_MASK) ++#define EP_CFG_MAXBURST_MAX 15 + /* ISO max burst. */ + #define EP_CFG_MULT_MASK GENMASK(15, 14) + #define EP_CFG_MULT(p) (((p) << 14) & EP_CFG_MULT_MASK) ++#define EP_CFG_MULT_MAX 2 + /* ISO max burst. */ + #define EP_CFG_MAXPKTSIZE_MASK GENMASK(26, 16) + #define EP_CFG_MAXPKTSIZE(p) (((p) << 16) & EP_CFG_MAXPKTSIZE_MASK) + /* Max number of buffered packets. */ + #define EP_CFG_BUFFERING_MASK GENMASK(31, 27) + #define EP_CFG_BUFFERING(p) (((p) << 27) & EP_CFG_BUFFERING_MASK) ++#define EP_CFG_BUFFERING_MAX 15 + + /* EP_CMD - bitmasks */ + /* Endpoint reset. */ +@@ -1094,9 +1097,6 @@ struct cdns3_trb { + #define CDNS3_ENDPOINTS_MAX_COUNT 32 + #define CDNS3_EP_ZLP_BUF_SIZE 1024 + +-#define CDNS3_EP_BUF_SIZE 4 /* KB */ +-#define CDNS3_EP_ISO_HS_MULT 3 +-#define CDNS3_EP_ISO_SS_BURST 3 + #define CDNS3_MAX_NUM_DESCMISS_BUF 32 + #define CDNS3_DESCMIS_BUF_SIZE 2048 /* Bytes */ + #define CDNS3_WA2_NUM_BUFFERS 128 +@@ -1333,6 +1333,9 @@ struct cdns3_device { + /*in KB */ + u16 onchip_buffers; + u16 onchip_used_size; ++ ++ u16 ep_buf_size; ++ u16 ep_iso_burst; + }; + + void cdns3_set_register_bit(void __iomem *ptr, u32 mask); +-- +2.39.2 + diff --git a/queue-5.15/usb-cdns3-fix-ncm-gadget-rx-speed-20x-slow-than-expe.patch b/queue-5.15/usb-cdns3-fix-ncm-gadget-rx-speed-20x-slow-than-expe.patch new file mode 100644 index 00000000000..5ba79f00440 --- /dev/null +++ b/queue-5.15/usb-cdns3-fix-ncm-gadget-rx-speed-20x-slow-than-expe.patch @@ -0,0 +1,63 @@ +From 3ddff533f7fa4e9d6434ac0e9d8f701d3e0d2107 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 May 2023 11:49:45 -0400 +Subject: usb: cdns3: fix NCM gadget RX speed 20x slow than expection at iMX8QM + +From: Frank Li + +[ Upstream commit dbe678f6192f27879ac9ff6bc7a1036aad85aae9 ] + +At iMX8QM platform, enable NCM gadget and run 'iperf3 -s'. +At host, run 'iperf3 -V -c fe80::6863:98ff:feef:3e0%enxc6e147509498' + +[ 5] 0.00-1.00 sec 1.55 MBytes 13.0 Mbits/sec 90 4.18 KBytes +[ 5] 1.00-2.00 sec 1.44 MBytes 12.0 Mbits/sec 75 4.18 KBytes +[ 5] 2.00-3.00 sec 1.48 MBytes 12.4 Mbits/sec 75 4.18 KBytes + +Expected speed should be bigger than 300Mbits/sec. + +The root cause of this performance drop was found to be data corruption +happening at 4K borders in some Ethernet packets, leading to TCP +checksum errors. This corruption occurs from the position +(4K - (address & 0x7F)) to 4K. The u_ether function's allocation of +skb_buff reserves 64B, meaning all RX addresses resemble 0xXXXX0040. + +Force trb_burst_size to 16 can fix this problem. + +Cc: stable@vger.kernel.org +Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver") +Signed-off-by: Frank Li +Link: https://lore.kernel.org/r/20230518154946.3666662-1-Frank.Li@nxp.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/cdns3/cdns3-gadget.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/drivers/usb/cdns3/cdns3-gadget.c b/drivers/usb/cdns3/cdns3-gadget.c +index ccfaebca6faa7..1dcadef933e3a 100644 +--- a/drivers/usb/cdns3/cdns3-gadget.c ++++ b/drivers/usb/cdns3/cdns3-gadget.c +@@ -2097,6 +2097,19 @@ int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable) + else + priv_ep->trb_burst_size = 16; + ++ /* ++ * In versions preceding DEV_VER_V2, for example, iMX8QM, there exit the bugs ++ * in the DMA. These bugs occur when the trb_burst_size exceeds 16 and the ++ * address is not aligned to 128 Bytes (which is a product of the 64-bit AXI ++ * and AXI maximum burst length of 16 or 0xF+1, dma_axi_ctrl0[3:0]). This ++ * results in data corruption when it crosses the 4K border. The corruption ++ * specifically occurs from the position (4K - (address & 0x7F)) to 4K. ++ * ++ * So force trb_burst_size to 16 at such platform. ++ */ ++ if (priv_dev->dev_ver < DEV_VER_V2) ++ priv_ep->trb_burst_size = 16; ++ + mult = min_t(u8, mult, EP_CFG_MULT_MAX); + buffering = min_t(u8, buffering, EP_CFG_BUFFERING_MAX); + maxburst = min_t(u8, maxburst, EP_CFG_MAXBURST_MAX); +-- +2.39.2 +