Message ID | 20210810060228.GA3326442@ubuntu |
---|---|
State | New |
Headers | show |
Series | usb: chipidea: fix RT issue for udc | expand |
On Tue, Aug 10, 2021 at 03:02:28PM +0900, Jeaho Hwang wrote: > 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. > > Signed-off-by: Jeaho Hwang <jhhwang@rtst.co.kr> > --- > drivers/usb/chipidea/udc.c | 31 +++++++++++++++++++++++++------ > 1 file changed, 25 insertions(+), 6 deletions(-) > > diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c > index 5f35cdd2cf1d..a90498f17cc4 100644 > --- a/drivers/usb/chipidea/udc.c > +++ b/drivers/usb/chipidea/udc.c > @@ -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 :(
On 21-08-10 15:02:28, Jeaho Hwang wrote: > 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. 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 > > Signed-off-by: Jeaho Hwang <jhhwang@rtst.co.kr> > --- > drivers/usb/chipidea/udc.c | 31 +++++++++++++++++++++++++------ > 1 file changed, 25 insertions(+), 6 deletions(-) > > diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c > index 5f35cdd2cf1d..a90498f17cc4 100644 > --- a/drivers/usb/chipidea/udc.c > +++ b/drivers/usb/chipidea/udc.c > @@ -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; > } > > /** > -- > 2.25.1 > -- Thanks, Peter Chen
On Mon, Aug 16, 2021 at 08:52:06AM +0800, Peter Chen wrote: > On 21-08-10 15:02:28, Jeaho Hwang wrote: > > 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. > > 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 <stern@rowland.harvard.edu>님이 작성: > > On Mon, Aug 16, 2021 at 08:52:06AM +0800, Peter Chen wrote: > > On 21-08-10 15:02:28, Jeaho Hwang wrote: > > > 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. > > > > 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. > > Alan Stern
On Mon, Aug 16, 2021 at 08:52:06AM +0800, Peter Chen wrote: > On 21-08-10 15:02:28, Jeaho Hwang wrote: > > 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. > > 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 <gregkh@linuxfoundation.org>님이 작성: > > On Mon, Aug 16, 2021 at 08:52:06AM +0800, Peter Chen wrote: > > On 21-08-10 15:02:28, Jeaho Hwang wrote: > > > 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. > > > > 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? -- 황재호, Jay Hwang, linux team manager of RTst 010-7242-1593
On Mon, Aug 16, 2021 at 04:10:46PM +0900, Jeaho Hwang wrote: > 2021년 8월 16일 (월) 오후 2:22, Greg Kroah-Hartman <gregkh@linuxfoundation.org>님이 작성: > > > > On Mon, Aug 16, 2021 at 08:52:06AM +0800, Peter Chen wrote: > > > On 21-08-10 15:02:28, Jeaho Hwang wrote: > > > > 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. > > > > > > 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
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 5f35cdd2cf1d..a90498f17cc4 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -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; } /**
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. Signed-off-by: Jeaho Hwang <jhhwang@rtst.co.kr> --- drivers/usb/chipidea/udc.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-)