usb: chipidea: fix RT issue for udc
Subsystems (2)
PATCH 1/1 usb: chipidea: fix RT issue for udc
hw_ep_prime sometimes fails if irq occurs while it rus on RT kernel. to prevent local_irq_save should keep the function from irqs.
I am not sure where is the best to submit this patch, between RT and USB community so sending to both. thanks.
--- drivers/usb/chipidea/udc.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-)
drivers/usb/chipidea/udc.c +17 -4
@@ -102,6 +102,9 @@ static int hw_ep_flush(struct ci_hdrc *ci, int num, int dir) {int n =hw_ep_bit (num, dir); +/* From zynq-7000 TRM, It can take a long time +* so irq disable is not a good option for RT +*/ do { /* flush any pending transfer */ hw_write(ci, OP_ENDPTFLUSH, ~0, BIT(n));
@@ -190,22 +193,32 @@ static int hw_ep_get_halt(struct ci_hdrc *ci, int num, int dir)static int hw_ep_prime (struct ci_hdrc *ci,int num,int dir,int is_ctrl) {int n =hw_ep_bit (num, dir); +unsigned long flags; +int ret =0 ;/* Synchronize before ep prime */ wmb (); -if (is_ctrl && dir ==RX &&hw_read (ci,OP_ENDPTSETUPSTAT ,BIT (num))) -return -EAGAIN ; +/* irq affects this routine so irq should be disabled on RT. +* on standard kernel, irq is already disabled by callers. +*/ +local_irq_save (flags); +if (is_ctrl && dir ==RX &&hw_read (ci,OP_ENDPTSETUPSTAT ,BIT (num))) { + ret = -EAGAIN ; + goto out; + }hw_write (ci,OP_ENDPTPRIME , ~0 ,BIT (n));while (hw_read (ci,OP_ENDPTPRIME ,BIT (n)))cpu_relax ();if (is_ctrl && dir ==RX &&hw_read (ci,OP_ENDPTSETUPSTAT ,BIT (num))) -return -EAGAIN ; + ret = -EAGAIN ; +out: +local_irq_restore (flags);/* status shoult be tested according with manual but it doesn't work */ -return 0 ; +return ret; }/**
Signature · 1 line
2.25.1
Greg Kroah-Hartman
maintainerQuoted 16 lines · Jeaho Hwang
hw_ep_primesometimes fails if irq occurs while it rus on RT kernel. to preventlocal_irq_saveshould keep the function from irqs.I am not sure where is the best to submit this patch, between RT and USB community so sending to both. thanks.
Signed-off-by Jeaho Hwang <[email protected]>--- drivers/usb/chipidea/udc.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-)drivers/usb/chipidea/udc.c +0
-0
drivers/usb/chipidea/udc.c static int hw_ep_flush(struct ci_hdrc *ci, int num, int dir) · line 107
Quoted 6 lines
drivers/usb/chipidea/udc.c +3
-0@@ -102,6 +102,9 @@ static int hw_ep_flush(struct ci_hdrc *ci, int num, int dir) {int n =hw_ep_bit (num, dir); +/* From zynq-7000 TRM, It can take a long time +* so irq disable is not a good option for RT +*/
Please use checkpatch.pl when submitting patches :(
Peter Chen
maintainerQuoted 5 lines · Jeaho Hwang
hw_ep_primesometimes fails if irq occurs while it rus on RT kernel. to preventlocal_irq_saveshould keep the function from irqs.I am not sure where is the best to submit this patch, between RT and USB community so sending to both. thanks.
Greg, do you have any suggestions about it, the RT kernel schedules the interrupt handler (top-half) out which causes the USB hardware atomic sequences are broken, these hardware operations needs to be executed within limited time.
Peter
Quoted 60 lines
Signed-off-by Jeaho Hwang <[email protected]>--- drivers/usb/chipidea/udc.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-)drivers/usb/chipidea/udc.c +17
-4@@ -102,6 +102,9 @@ static int hw_ep_flush(struct ci_hdrc *ci, int num, int dir) {int n =hw_ep_bit (num, dir); +/* From zynq-7000 TRM, It can take a long time +* so irq disable is not a good option for RT +*/ do { /* flush any pending transfer */ hw_write(ci, OP_ENDPTFLUSH, ~0, BIT(n));@@ -190,22 +193,32 @@ static int hw_ep_get_halt(struct ci_hdrc *ci, int num, int dir)static int hw_ep_prime (struct ci_hdrc *ci,int num,int dir,int is_ctrl) {int n =hw_ep_bit (num, dir); +unsigned long flags; +int ret =0 ;/* Synchronize before ep prime */ wmb (); -if (is_ctrl && dir ==RX &&hw_read (ci,OP_ENDPTSETUPSTAT ,BIT (num))) -return -EAGAIN ; +/* irq affects this routine so irq should be disabled on RT. +* on standard kernel, irq is already disabled by callers. +*/ +local_irq_save (flags); +if (is_ctrl && dir ==RX &&hw_read (ci,OP_ENDPTSETUPSTAT ,BIT (num))) { + ret = -EAGAIN ; + goto out; + }hw_write (ci,OP_ENDPTPRIME , ~0 ,BIT (n));while (hw_read (ci,OP_ENDPTPRIME ,BIT (n)))cpu_relax ();if (is_ctrl && dir ==RX &&hw_read (ci,OP_ENDPTSETUPSTAT ,BIT (num))) -return -EAGAIN ; + ret = -EAGAIN ; +out: +local_irq_restore (flags);/* status shoult be tested according with manual but it doesn't work */ -return 0 ; +return ret; }/** Signature · 1 line
2.25.1
Signature · 2 lines
Thanks, Peter Chen
Quoted 10 lines · Peter Chen
Quoted 5 lines · Jeaho Hwang
hw_ep_primesometimes fails if irq occurs while it rus on RT kernel. to preventlocal_irq_saveshould keep the function from irqs.I am not sure where is the best to submit this patch, between RT and USB community so sending to both. thanks.
Greg, do you have any suggestions about it, the RT kernel schedules the interrupt handler (top-half) out which causes the USB hardware atomic sequences are broken, these hardware operations needs to be executed within limited time.
The RT kernel does its scheduling based on priorities. If the interrupt handler is scheduled out, it's because some other process with a higher priority needs to run. The answer should be to increase the handler's priority.
Alan Stern
2021년 8월 16일 (월) 오전 10:03, Alan Stern <[email protected]>님이 작성:
Quoted 9 lines · Peter Chen
Quoted 7 lines · Jeaho Hwang
Quoted 5 lines
hw_ep_primesometimes fails if irq occurs while it rus on RT kernel. to preventlocal_irq_saveshould keep the function from irqs.I am not sure where is the best to submit this patch, between RT and USB community so sending to both. thanks.
Quoted 8 lines
Quoted 3 lines
Greg, do you have any suggestions about it, the RT kernel schedules the interrupt handler (top-half) out which causes the USB hardware atomic sequences are broken, these hardware operations needs to be executed within limited time.
The RT kernel does its scheduling based on priorities. If the interrupt handler is scheduled out, it's because some other process with a higher priority needs to run. The answer should be to increase the handler's priority.
It is not a schedule issue. Priority does not prevent atomic sequences from irq handlers which run in interrupt context. So we added local_irq_save to protect explicitly and asked if it is the right approach.
In addition, I've checked if all functions in udc.c, which have the comment "execute without interruption", need to be protected from irqs. And I think no need for the others since they don't seem to have any contention between tasks and the chip as hw_ep_prime has.
Thanks.
Quoted 2 lines
Alan Stern
Greg Kroah-Hartman
maintainerQuoted 10 lines · Peter Chen
Quoted 5 lines · Jeaho Hwang
hw_ep_primesometimes fails if irq occurs while it rus on RT kernel. to preventlocal_irq_saveshould keep the function from irqs.I am not sure where is the best to submit this patch, between RT and USB community so sending to both. thanks.
Greg, do you have any suggestions about it, the RT kernel schedules the interrupt handler (top-half) out which causes the USB hardware atomic sequences are broken, these hardware operations needs to be executed within limited time.
Try working with the RT developers on this.
2021년 8월 16일 (월) 오후 2:22, Greg Kroah-Hartman <[email protected]>님이 작성:
Quoted 6 lines · Peter Chen
Quoted 4 lines · Jeaho Hwang
Quoted 3 lines
hw_ep_primesometimes fails if irq occurs while it rus on RT kernel. to preventlocal_irq_saveshould keep the function from irqs.
Quoted 8 lines
Quoted 6 lines
Quoted 2 lines
I am not sure where is the best to submit this patch, between RT and USB community so sending to both. thanks.
Greg, do you have any suggestions about it, the RT kernel schedules the interrupt handler (top-half) out which causes the USB hardware atomic sequences are broken, these hardware operations needs to be executed within limited time.
Try working with the RT developers on this.
Then do you think those kinds of patches should be applied to linux-rt instead of mainline?
Signature · 2 lines
황재호, Jay Hwang, linux team manager of RTst 010-7242-1593
Greg Kroah-Hartman
maintainerQuoted 10 lines · Jeaho Hwang
2021년 8월 16일 (월) 오후 2:22, Greg Kroah-Hartman <[email protected]>님이 작성:
Quoted 9 lines · Peter Chen
Quoted 7 lines · Jeaho Hwang
Quoted 5 lines
hw_ep_primesometimes fails if irq occurs while it rus on RT kernel. to preventlocal_irq_saveshould keep the function from irqs.I am not sure where is the best to submit this patch, between RT and USB community so sending to both. thanks.
Quoted 8 lines
Quoted 5 lines
Quoted 3 lines
Greg, do you have any suggestions about it, the RT kernel schedules the interrupt handler (top-half) out which causes the USB hardware atomic sequences are broken, these hardware operations needs to be executed within limited time.
Try working with the RT developers on this.
Then do you think those kinds of patches should be applied to linux-rt instead of mainline?
Depends on the resulting patch, if it is something that works for mainline, then we will take it, otherwise if it is rt-only and is not acceptable for mainline at this point in time, then it needs to go to the rt tree until someone fixes it up there such that it can be accepted.
thanks,
greg k-h