Oliver Endriss wrote: > Johannes Stezenbach wrote: > > I just fixed a bug in timeout handling: > > > > start = jiffies; > > while (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2 )) { > > - msleep(1); > > if (time_after(jiffies, start + ARM_WAIT_FREE)) { > > printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND idle\n", __FUNCTION__); > > return -ETIMEDOUT; > > } > > + msleep(1); > > } > > > > (multiple occurences) > > > > When the machine is busy, msleep(1) can sleep unexpectedly long. > > Additionally, it doesn't make sense to sleep and then exit with > > a timeout without retesting the condition we're waiting for. > > The code above is better but does not solve the problem completely. > I still had problems under high CPU load with a preemptible kernel. > > Imho it should be done this way: > > while (1) { > err = time_after(jiffies, start + ARM_WAIT_FREE); > if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0) > break; > if (err) { > printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND idle\n", __FUNCTION__); > return -ETIMEDOUT; > } > msleep(1); > } > > This way rdebi can always be executed at the end of the timeout period. > Now the scheduler may suspend the task everywhere in the loop for an > extended period of time. > > If no one objects I will apply the patch to av7110_hw.c and > saa7146_core.c/wait_for_debi_done(). Good catch! Pretty subtle, though... Johannes