linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] usb: xhci-mtk: fix fs isoc's transfer error
@ 2022-05-12  6:49 Chunfeng Yun
  2022-05-12  6:49 ` [PATCH 2/2] usb: xhci-mtk: remove bandwidth budget table Chunfeng Yun
  2022-05-18 12:01 ` [PATCH 1/2] usb: xhci-mtk: fix fs isoc's transfer error AngeloGioacchino Del Regno
  0 siblings, 2 replies; 4+ messages in thread
From: Chunfeng Yun @ 2022-05-12  6:49 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Mathias Nyman, Chunfeng Yun, Matthias Brugger, linux-usb,
	linux-arm-kernel, linux-mediatek, linux-kernel, Eddie Hung,
	Tianping Fang, stable

Due to the scheduler allocates the optimal bandwidth for FS ISOC endpoints,
this may be not enough actually and causes data transfer error, so come up
with an estimate that is no less than the worst case bandwidth used for
any one mframe, but may be an over-estimate.

Fixes: 451d3912586a ("usb: xhci-mtk: update fs bus bandwidth by bw_budget_table")
Cc: stable@vger.kernel.org
Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
---
 drivers/usb/host/xhci-mtk-sch.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c
index f3139ce7b0a9..953d2cd1d4cc 100644
--- a/drivers/usb/host/xhci-mtk-sch.c
+++ b/drivers/usb/host/xhci-mtk-sch.c
@@ -464,7 +464,7 @@ static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset)
 		 */
 		for (j = 0; j < sch_ep->num_budget_microframes; j++) {
 			k = XHCI_MTK_BW_INDEX(base + j);
-			tmp = tt->fs_bus_bw[k] + sch_ep->bw_budget_table[j];
+			tmp = tt->fs_bus_bw[k] + sch_ep->bw_cost_per_microframe;
 			if (tmp > FS_PAYLOAD_MAX)
 				return -ESCH_BW_OVERFLOW;
 		}
@@ -538,19 +538,17 @@ static int check_sch_tt(struct mu3h_sch_ep_info *sch_ep, u32 offset)
 static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used)
 {
 	struct mu3h_sch_tt *tt = sch_ep->sch_tt;
+	int bw_updated;
 	u32 base;
-	int i, j, k;
+	int i, j;
+
+	bw_updated = sch_ep->bw_cost_per_microframe * (used ? 1 : -1);
 
 	for (i = 0; i < sch_ep->num_esit; i++) {
 		base = sch_ep->offset + i * sch_ep->esit;
 
-		for (j = 0; j < sch_ep->num_budget_microframes; j++) {
-			k = XHCI_MTK_BW_INDEX(base + j);
-			if (used)
-				tt->fs_bus_bw[k] += sch_ep->bw_budget_table[j];
-			else
-				tt->fs_bus_bw[k] -= sch_ep->bw_budget_table[j];
-		}
+		for (j = 0; j < sch_ep->num_budget_microframes; j++)
+			tt->fs_bus_bw[XHCI_MTK_BW_INDEX(base + j)] += bw_updated;
 	}
 
 	if (used)
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/2] usb: xhci-mtk: remove bandwidth budget table
  2022-05-12  6:49 [PATCH 1/2] usb: xhci-mtk: fix fs isoc's transfer error Chunfeng Yun
@ 2022-05-12  6:49 ` Chunfeng Yun
  2022-05-18 12:01 ` [PATCH 1/2] usb: xhci-mtk: fix fs isoc's transfer error AngeloGioacchino Del Regno
  1 sibling, 0 replies; 4+ messages in thread
From: Chunfeng Yun @ 2022-05-12  6:49 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Mathias Nyman, Chunfeng Yun, Matthias Brugger, linux-usb,
	linux-arm-kernel, linux-mediatek, linux-kernel, Eddie Hung,
	Tianping Fang

The bandwidth budget table is introduced to trace ideal bandwidth used
by each INT/ISOC endpoint, but in fact the endpoint may consume more
bandwidth and cause data transfer error, so it's better to leave some
margin. Obviously it's difficult to find the best margin for all cases,
instead take use of the worst-case scenario.

Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
---
 drivers/usb/host/xhci-mtk-sch.c | 74 ++++++---------------------------
 drivers/usb/host/xhci-mtk.h     |  2 -
 2 files changed, 12 insertions(+), 64 deletions(-)

diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c
index 953d2cd1d4cc..06a6b19acaae 100644
--- a/drivers/usb/host/xhci-mtk-sch.c
+++ b/drivers/usb/host/xhci-mtk-sch.c
@@ -19,11 +19,6 @@
 #define HS_BW_BOUNDARY	6144
 /* usb2 spec section11.18.1: at most 188 FS bytes per microframe */
 #define FS_PAYLOAD_MAX 188
-/*
- * max number of microframes for split transfer,
- * for fs isoc in : 1 ss + 1 idle + 7 cs
- */
-#define TT_MICROFRAMES_MAX 9
 
 #define DBG_BUF_EN	64
 
@@ -242,28 +237,17 @@ static void drop_tt(struct usb_device *udev)
 
 static struct mu3h_sch_ep_info *
 create_sch_ep(struct xhci_hcd_mtk *mtk, struct usb_device *udev,
-	      struct usb_host_endpoint *ep, struct xhci_ep_ctx *ep_ctx)
+	      struct usb_host_endpoint *ep)
 {
 	struct mu3h_sch_ep_info *sch_ep;
 	struct mu3h_sch_bw_info *bw_info;
 	struct mu3h_sch_tt *tt = NULL;
-	u32 len_bw_budget_table;
 
 	bw_info = get_bw_info(mtk, udev, ep);
 	if (!bw_info)
 		return ERR_PTR(-ENODEV);
 
-	if (is_fs_or_ls(udev->speed))
-		len_bw_budget_table = TT_MICROFRAMES_MAX;
-	else if ((udev->speed >= USB_SPEED_SUPER)
-			&& usb_endpoint_xfer_isoc(&ep->desc))
-		len_bw_budget_table = get_esit(ep_ctx);
-	else
-		len_bw_budget_table = 1;
-
-	sch_ep = kzalloc(struct_size(sch_ep, bw_budget_table,
-				     len_bw_budget_table),
-			 GFP_KERNEL);
+	sch_ep = kzalloc(sizeof(*sch_ep), GFP_KERNEL);
 	if (!sch_ep)
 		return ERR_PTR(-ENOMEM);
 
@@ -295,8 +279,6 @@ static void setup_sch_info(struct xhci_ep_ctx *ep_ctx,
 	u32 mult;
 	u32 esit_pkts;
 	u32 max_esit_payload;
-	u32 *bwb_table = sch_ep->bw_budget_table;
-	int i;
 
 	ep_type = CTX_TO_EP_TYPE(le32_to_cpu(ep_ctx->ep_info2));
 	maxpkt = MAX_PACKET_DECODED(le32_to_cpu(ep_ctx->ep_info2));
@@ -332,7 +314,6 @@ static void setup_sch_info(struct xhci_ep_ctx *ep_ctx,
 		 */
 		sch_ep->pkts = max_burst + 1;
 		sch_ep->bw_cost_per_microframe = maxpkt * sch_ep->pkts;
-		bwb_table[0] = sch_ep->bw_cost_per_microframe;
 	} else if (sch_ep->speed >= USB_SPEED_SUPER) {
 		/* usb3_r1 spec section4.4.7 & 4.4.8 */
 		sch_ep->cs_count = 0;
@@ -349,7 +330,6 @@ static void setup_sch_info(struct xhci_ep_ctx *ep_ctx,
 		if (ep_type == INT_IN_EP || ep_type == INT_OUT_EP) {
 			sch_ep->pkts = esit_pkts;
 			sch_ep->num_budget_microframes = 1;
-			bwb_table[0] = maxpkt * sch_ep->pkts;
 		}
 
 		if (ep_type == ISOC_IN_EP || ep_type == ISOC_OUT_EP) {
@@ -366,15 +346,8 @@ static void setup_sch_info(struct xhci_ep_ctx *ep_ctx,
 				DIV_ROUND_UP(esit_pkts, sch_ep->pkts);
 
 			sch_ep->repeat = !!(sch_ep->num_budget_microframes > 1);
-			sch_ep->bw_cost_per_microframe = maxpkt * sch_ep->pkts;
-
-			for (i = 0; i < sch_ep->num_budget_microframes - 1; i++)
-				bwb_table[i] = sch_ep->bw_cost_per_microframe;
-
-			/* last one <= bw_cost_per_microframe */
-			bwb_table[i] = maxpkt * esit_pkts
-				       - i * sch_ep->bw_cost_per_microframe;
 		}
+		sch_ep->bw_cost_per_microframe = maxpkt * sch_ep->pkts;
 	} else if (is_fs_or_ls(sch_ep->speed)) {
 		sch_ep->pkts = 1; /* at most one packet for each microframe */
 
@@ -384,28 +357,7 @@ static void setup_sch_info(struct xhci_ep_ctx *ep_ctx,
 		 */
 		sch_ep->cs_count = DIV_ROUND_UP(maxpkt, FS_PAYLOAD_MAX);
 		sch_ep->num_budget_microframes = sch_ep->cs_count;
-		sch_ep->bw_cost_per_microframe =
-			(maxpkt < FS_PAYLOAD_MAX) ? maxpkt : FS_PAYLOAD_MAX;
-
-		/* init budget table */
-		if (ep_type == ISOC_OUT_EP) {
-			for (i = 0; i < sch_ep->num_budget_microframes; i++)
-				bwb_table[i] =	sch_ep->bw_cost_per_microframe;
-		} else if (ep_type == INT_OUT_EP) {
-			/* only first one consumes bandwidth, others as zero */
-			bwb_table[0] = sch_ep->bw_cost_per_microframe;
-		} else { /* INT_IN_EP or ISOC_IN_EP */
-			bwb_table[0] = 0; /* start split */
-			bwb_table[1] = 0; /* idle */
-			/*
-			 * due to cs_count will be updated according to cs
-			 * position, assign all remainder budget array
-			 * elements as @bw_cost_per_microframe, but only first
-			 * @num_budget_microframes elements will be used later
-			 */
-			for (i = 2; i < TT_MICROFRAMES_MAX; i++)
-				bwb_table[i] =	sch_ep->bw_cost_per_microframe;
-		}
+		sch_ep->bw_cost_per_microframe = min_t(u32, maxpkt, FS_PAYLOAD_MAX);
 	}
 }
 
@@ -422,7 +374,7 @@ static u32 get_max_bw(struct mu3h_sch_bw_info *sch_bw,
 
 		for (j = 0; j < sch_ep->num_budget_microframes; j++) {
 			k = XHCI_MTK_BW_INDEX(base + j);
-			bw = sch_bw->bus_bw[k] + sch_ep->bw_budget_table[j];
+			bw = sch_bw->bus_bw[k] + sch_ep->bw_cost_per_microframe;
 			if (bw > max_bw)
 				max_bw = bw;
 		}
@@ -433,18 +385,16 @@ static u32 get_max_bw(struct mu3h_sch_bw_info *sch_bw,
 static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw,
 	struct mu3h_sch_ep_info *sch_ep, bool used)
 {
+	int bw_updated;
 	u32 base;
-	int i, j, k;
+	int i, j;
+
+	bw_updated = sch_ep->bw_cost_per_microframe * (used ? 1 : -1);
 
 	for (i = 0; i < sch_ep->num_esit; i++) {
 		base = sch_ep->offset + i * sch_ep->esit;
-		for (j = 0; j < sch_ep->num_budget_microframes; j++) {
-			k = XHCI_MTK_BW_INDEX(base + j);
-			if (used)
-				sch_bw->bus_bw[k] += sch_ep->bw_budget_table[j];
-			else
-				sch_bw->bus_bw[k] -= sch_ep->bw_budget_table[j];
-		}
+		for (j = 0; j < sch_ep->num_budget_microframes; j++)
+			sch_bw->bus_bw[XHCI_MTK_BW_INDEX(base + j)] += bw_updated;
 	}
 }
 
@@ -708,7 +658,7 @@ static int add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
 
 	xhci_dbg(xhci, "%s %s\n", __func__, decode_ep(ep, udev->speed));
 
-	sch_ep = create_sch_ep(mtk, udev, ep, ep_ctx);
+	sch_ep = create_sch_ep(mtk, udev, ep);
 	if (IS_ERR_OR_NULL(sch_ep))
 		return -ENOMEM;
 
diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h
index ffd4b493b4ba..1174a510dd38 100644
--- a/drivers/usb/host/xhci-mtk.h
+++ b/drivers/usb/host/xhci-mtk.h
@@ -83,7 +83,6 @@ struct mu3h_sch_bw_info {
  *		times; 1: distribute the (bMaxBurst+1)*(Mult+1) packets
  *		according to @pkts and @repeat. normal mode is used by
  *		default
- * @bw_budget_table: table to record bandwidth budget per microframe
  */
 struct mu3h_sch_ep_info {
 	u32 esit;
@@ -109,7 +108,6 @@ struct mu3h_sch_ep_info {
 	u32 pkts;
 	u32 cs_count;
 	u32 burst_mode;
-	u32 bw_budget_table[];
 };
 
 #define MU3C_U3_PORT_MAX 4
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 1/2] usb: xhci-mtk: fix fs isoc's transfer error
  2022-05-12  6:49 [PATCH 1/2] usb: xhci-mtk: fix fs isoc's transfer error Chunfeng Yun
  2022-05-12  6:49 ` [PATCH 2/2] usb: xhci-mtk: remove bandwidth budget table Chunfeng Yun
@ 2022-05-18 12:01 ` AngeloGioacchino Del Regno
  2022-05-23  8:55   ` Chunfeng Yun
  1 sibling, 1 reply; 4+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-05-18 12:01 UTC (permalink / raw)
  To: Chunfeng Yun, Greg Kroah-Hartman
  Cc: Mathias Nyman, Matthias Brugger, linux-usb, linux-arm-kernel,
	linux-mediatek, linux-kernel, Eddie Hung, Tianping Fang, stable

Il 12/05/22 08:49, Chunfeng Yun ha scritto:
> Due to the scheduler allocates the optimal bandwidth for FS ISOC endpoints,
> this may be not enough actually and causes data transfer error, so come up
> with an estimate that is no less than the worst case bandwidth used for
> any one mframe, but may be an over-estimate.
> 
> Fixes: 451d3912586a ("usb: xhci-mtk: update fs bus bandwidth by bw_budget_table")
> Cc: stable@vger.kernel.org
> Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>

Hello Chunfeng,
I agree this is "a fix"... but is it the best fix?

Shooting the bandwidth very high will have power consumption consequences, are
those measurable?
And if they are, what is the expected power consumption increase in percentage
(and/or microamperes)? Also, out of the expected increase, have you got any
measurement for that?

Assuming that the measurement is done for one SoC, it's possible to make some
assumption about a different part.

Regards,
Angelo

> ---
>   drivers/usb/host/xhci-mtk-sch.c | 16 +++++++---------
>   1 file changed, 7 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c
> index f3139ce7b0a9..953d2cd1d4cc 100644
> --- a/drivers/usb/host/xhci-mtk-sch.c
> +++ b/drivers/usb/host/xhci-mtk-sch.c

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 1/2] usb: xhci-mtk: fix fs isoc's transfer error
  2022-05-18 12:01 ` [PATCH 1/2] usb: xhci-mtk: fix fs isoc's transfer error AngeloGioacchino Del Regno
@ 2022-05-23  8:55   ` Chunfeng Yun
  0 siblings, 0 replies; 4+ messages in thread
From: Chunfeng Yun @ 2022-05-23  8:55 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno, Greg Kroah-Hartman
  Cc: Mathias Nyman, Matthias Brugger, linux-usb, linux-arm-kernel,
	linux-mediatek, linux-kernel, Eddie Hung, Tianping Fang, stable

On Wed, 2022-05-18 at 14:01 +0200, AngeloGioacchino Del Regno wrote:
> Il 12/05/22 08:49, Chunfeng Yun ha scritto:
> > Due to the scheduler allocates the optimal bandwidth for FS ISOC
> > endpoints,
> > this may be not enough actually and causes data transfer error, so
> > come up
> > with an estimate that is no less than the worst case bandwidth used
> > for
> > any one mframe, but may be an over-estimate.
> > 
> > Fixes: 451d3912586a ("usb: xhci-mtk: update fs bus bandwidth by
> > bw_budget_table")
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
> 
> Hello Chunfeng,
> I agree this is "a fix"... but is it the best fix?
> 
> Shooting the bandwidth very high will have power consumption
> consequences, are
> those measurable?
This is usually limited into one interval; e.g. the last interval
transfers 8 bytes in fact, but I assume it may transfer 188 bytes, I
think the consumption increase can be ignored.

> And if they are, what is the expected power consumption increase in
> percentage
> (and/or microamperes)? Also, out of the expected increase, have you
> got any
> measurement for that?
> 
> Assuming that the measurement is done for one SoC, it's possible to
> make some
> assumption about a different part.
> 
> Regards,
> Angelo
> 
> > ---
> >   drivers/usb/host/xhci-mtk-sch.c | 16 +++++++---------
> >   1 file changed, 7 insertions(+), 9 deletions(-)
> > 
> > diff --git a/drivers/usb/host/xhci-mtk-sch.c
> > b/drivers/usb/host/xhci-mtk-sch.c
> > index f3139ce7b0a9..953d2cd1d4cc 100644
> > --- a/drivers/usb/host/xhci-mtk-sch.c
> > +++ b/drivers/usb/host/xhci-mtk-sch.c


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2022-05-23  8:56 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-12  6:49 [PATCH 1/2] usb: xhci-mtk: fix fs isoc's transfer error Chunfeng Yun
2022-05-12  6:49 ` [PATCH 2/2] usb: xhci-mtk: remove bandwidth budget table Chunfeng Yun
2022-05-18 12:01 ` [PATCH 1/2] usb: xhci-mtk: fix fs isoc's transfer error AngeloGioacchino Del Regno
2022-05-23  8:55   ` Chunfeng Yun

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).