Antonio Pérez
2016-May-26 17:57 UTC
[Nut-upsdev] A lot of EAGAIN (Resource temporarily unavailable) using nutdrv_qx
Hello,
I have a Salicru UPS connected by USB using nutdrv_qx driver. As I see
that it was using too much CPU time (or at least, too much for what I
think it should be normal), I used strace to see what is was using,
and got a lot of lines like these:
%<------------%<------------%<------------%<------------
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffdca143278) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 0 (Timeout)
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffdca143278) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 0 (Timeout)
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffdca143278) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 0 (Timeout)
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffdca143278) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 0 (Timeout)
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffdca143278) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 0 (Timeout)
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffdca143278) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 0 (Timeout)
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffdca143278) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 0 (Timeout)
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffdca143278) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 0 (Timeout)
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffdca143278) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 0 (Timeout)
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffdca143278) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 0 (Timeout)
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffdca143278) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 0 (Timeout)
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffdca143278) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 0 (Timeout)
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffdca143278) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 0 (Timeout)
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffdca143278) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 0 (Timeout)
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffdca143278) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 0 (Timeout)
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffdca143278) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 0 (Timeout)
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffdca143278) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 0 (Timeout)
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffdca143278) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 0 (Timeout)
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffdca143278) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 0 (Timeout)
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffdca143278) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 0 (Timeout)
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffdca143278) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 0 (Timeout)
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffdca143278) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 0 (Timeout)
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffdca143278) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 0 (Timeout)
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffdca143278) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 0 (Timeout)
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffdca143278) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 0 (Timeout)
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffdca143278) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 0 (Timeout)
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffdca143278) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 0 (Timeout)
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffdca143278) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 0 (Timeout)
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffdca143278) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 0 (Timeout)
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffdca143278) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 0 (Timeout)
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffdca143278) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 0 (Timeout)
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffdca143278) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 1 (out [4], left {0, 944})
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffdca143278) = 0
write(2, " 42.693227\t", 12) = 12
write(2, "read: (224.4 224.4 224.4 007 50.0 13.7 --.- 00001001\n", 53)
= 53
write(2, " 42.693517\t", 12) = 12
write(2, "ups_infoval_set: non numerical value [ups.temperature:
--.-]\n", 61) = 61
%<------------%<------------%<------------%<------------
I downloaded the code and patched and compiled myself. Using some
"sleeps" it goes better, but not so fine I would like:
%<------------%<------------%<------------%<------------
write(2, "send: QS\n", 9) = 9
nanosleep({0, 100000000}, NULL) = 0
ioctl(4, USBDEVFS_SUBMITURB, 0x7ffc0d2c66e0) = 0
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffc0d2c66a8) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 1 (out [4], left {0, 564})
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffc0d2c66a8) = 0
nanosleep({0, 100000000}, NULL) = 0
ioctl(4, USBDEVFS_SUBMITURB, 0x7ffc0d2c66e0) = 0
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffc0d2c66a8) = 0
nanosleep({0, 100000000}, NULL) = 0
ioctl(4, USBDEVFS_SUBMITURB, 0x7ffc0d2c66e0) = 0
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffc0d2c66a8) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 0 (Timeout)
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffc0d2c66a8) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 0 (Timeout)
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffc0d2c66a8) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 1 (out [4], left {0, 923})
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffc0d2c66a8) = 0
nanosleep({0, 100000000}, NULL) = 0
ioctl(4, USBDEVFS_SUBMITURB, 0x7ffc0d2c66e0) = 0
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffc0d2c66a8) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 1 (out [4], left {0, 891})
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffc0d2c66a8) = 0
nanosleep({0, 100000000}, NULL) = 0
ioctl(4, USBDEVFS_SUBMITURB, 0x7ffc0d2c66e0) = 0
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffc0d2c66a8) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 1 (out [4], left {0, 993})
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffc0d2c66a8) = 0
nanosleep({0, 100000000}, NULL) = 0
ioctl(4, USBDEVFS_SUBMITURB, 0x7ffc0d2c66e0) = 0
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffc0d2c66a8) = -1 EAGAIN (Resource
temporarily unavailable)
select(5, NULL, [4], NULL, {0, 1000}) = 1 (out [4], left {0, 916})
ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffc0d2c66a8) = 0
write(2, " 34.057452\t", 12) = 12
write(2, "read: (226.5 226.5 226.5 007 50.0 13.7 --.- 00001001\n", 53)
= 53
write(2, " 34.057802\t", 12) = 12
write(2, "ups_infoval_set: non numerical value [ups.temperature:
--.-]\n", 61) = 61
%<------------%<------------%<------------%<------------
Is this the right behaviour? If not, could it goes better using
libusb-1.0? Are the port to libusb-1.0 in the roadmap?
Attached are a zip file with the full output of the original and the
patched version of the driver, if you need more information. I also
attach the patch applied.
Thank you very much for your time.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: nutdrv_qx_out.zip
Type: application/zip
Size: 6310 bytes
Desc: not available
URL:
<http://lists.alioth.debian.org/pipermail/nut-upsdev/attachments/20160526/1fa8070d/attachment.zip>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: nutdrv_qx.c-sleep.patch
Type: text/x-patch
Size: 505 bytes
Desc: not available
URL:
<http://lists.alioth.debian.org/pipermail/nut-upsdev/attachments/20160526/1fa8070d/attachment.bin>
Charles Lepple
2016-Jun-01 03:01 UTC
[Nut-upsdev] A lot of EAGAIN (Resource temporarily unavailable) using nutdrv_qx
On May 26, 2016, at 1:57 PM, Antonio P?rez <aperez at skarcha.com> wrote:> > I downloaded the code and patched and compiled myself. Using some > "sleeps" it goes better, but not so fine I would like: > > %<------------%<------------%<------------%<------------ > write(2, "send: QS\n", 9) = 9 > nanosleep({0, 100000000}, NULL) = 0 > ioctl(4, USBDEVFS_SUBMITURB, 0x7ffc0d2c66e0) = 0 > ioctl(4, USBDEVFS_REAPURBNDELAY, 0x7ffc0d2c66a8) = -1 EAGAIN (Resource > temporarily unavailable) > select(5, NULL, [4], NULL, {0, 1000}) = 1 (out [4], left {0, 564})How would you improve it? There will definitely be a tradeoff between responsiveness and CPU usage. I CC'd the author of nutdrv_qx - I think it could work to add a "usleep" corresponding to the approximate size of the sent and expected receive packet, but this would be different for 1.5 Mb/s and 12 Mb/s USB devices. You might also want to add timing numbers to the strace output (either "-tt" or "-T").> Is this the right behaviour? If not, could it goes better using > libusb-1.0? Are the port to libusb-1.0 in the roadmap?So far, there have not been any good arguments for libusb-1.0 that would offset the amount of testing needed. Feel free to experiment, though. For timing purposes, it should be sufficient to write a small loop that sends the command for your UPS, and reads the response via libusb-1.0 (rather than trying to port the entire NUT driver). -- Charles Lepple clepple at gmail