Reading accelerometer blocks the whole main event loop
We have some Acer Veriton Z4660G and Z4860G AIO desktops which equip with an accelerometer SMO8840.
We have traced the codes and found that g_timeout_add (700, poll_orientation, drv_data)
registers the poll_orientation
callback function. The function will be called each 700ms. However, the function takes 6~7 seconds for the execution which will block the main event loop. And each calling poll_orientation cannot be finished in each period 700 ms.
I add some debug messages as a patch in the attachment which logs into dmesg and chmod 777 /dev/kmsg
is needed. iio-sensor-proxy-to-upstream-diff.txt
I emulate as the gsd-power to send the dbus method call "ReleaseLight" to iio-sensor-proxy.
ps ax | grep iio; \
date; \
echo "Method call test start" >> /dev/kmsg; \
gdbus call --system --dest net.hadess.SensorProxy --object-path /net/hadess/SensorProxy --method net.hadess.SensorProxy.ReleaseLight; \
echo "Method call test end" >> /dev/kmsg; \
date; \
ps ax | grep iio
619 ? Dsl 0:00 /usr/sbin/iio-sensor-proxy
2434 pts/0 S+ 0:00 grep iio
Wed Nov 14 17:26:54 CST 2018
()
Wed Nov 14 17:27:04 CST 2018
619 ? Dsl 0:00 /usr/sbin/iio-sensor-proxy
2845 pts/0 R+ 0:00 grep iio
It takes about 10 seconds. We can get more detail timing in the dmesg:
[ 91.541552] Method call test start
[ 93.193693] iio-proxy: sysfs_get_int going to free /sys/devices/pci0000:00/0000:00:15.0/i2c_designware.0/i2c-7/i2c-SMO8840:00/iio:device0/in_accel_y_raw contents
[ 93.193699] iio-proxy: sysfs_get_int end
[ 93.193703] iio-proxy: sysfs_get_int start
[ 93.193712] iio-proxy: sysfs_get_int going to get /sys/devices/pci0000:00/0000:00:15.0/i2c_designware.0/i2c-7/i2c-SMO8840:00/iio:device0/in_accel_z_raw contents
[ 95.339109] iio-proxy: sysfs_get_int going to free /sys/devices/pci0000:00/0000:00:15.0/i2c_designware.0/i2c-7/i2c-SMO8840:00/iio:device0/in_accel_z_raw contents
[ 95.339115] iio-proxy: sysfs_get_int end
[ 95.339126] iio-proxy: accel_changed_func start
[ 95.339132] iio-proxy: accel_changed_func end
[ 95.339135] iio-proxy: poll_orientation end
[ 95.339147] iio-proxy: poll_orientation start
[ 95.339151] iio-proxy: sysfs_get_int start
[ 95.339158] iio-proxy: sysfs_get_int going to get /sys/devices/pci0000:00/0000:00:15.0/i2c_designware.0/i2c-7/i2c-SMO8840:00/iio:device0/in_accel_x_raw contents
[ 97.483265] iio-proxy: sysfs_get_int going to free /sys/devices/pci0000:00/0000:00:15.0/i2c_designware.0/i2c-7/i2c-SMO8840:00/iio:device0/in_accel_x_raw contents
[ 97.483272] iio-proxy: sysfs_get_int end
[ 97.483276] iio-proxy: sysfs_get_int start
[ 97.483288] iio-proxy: sysfs_get_int going to get /sys/devices/pci0000:00/0000:00:15.0/i2c_designware.0/i2c-7/i2c-SMO8840:00/iio:device0/in_accel_y_raw contents
[ 99.628640] iio-proxy: sysfs_get_int going to free /sys/devices/pci0000:00/0000:00:15.0/i2c_designware.0/i2c-7/i2c-SMO8840:00/iio:device0/in_accel_y_raw contents
[ 99.628648] iio-proxy: sysfs_get_int end
[ 99.628652] iio-proxy: sysfs_get_int start
[ 99.628662] iio-proxy: sysfs_get_int going to get /sys/devices/pci0000:00/0000:00:15.0/i2c_designware.0/i2c-7/i2c-SMO8840:00/iio:device0/in_accel_z_raw contents
[ 101.777200] iio-proxy: sysfs_get_int going to free /sys/devices/pci0000:00/0000:00:15.0/i2c_designware.0/i2c-7/i2c-SMO8840:00/iio:device0/in_accel_z_raw contents
[ 101.777208] iio-proxy: sysfs_get_int end
[ 101.777223] iio-proxy: accel_changed_func start
[ 101.777230] iio-proxy: accel_changed_func end
[ 101.777234] iio-proxy: poll_orientation end
[ 101.777245] iio-proxy: handle_method_call start, method_name: ReleaseLight
[ 101.777251] iio-proxy: handle_generic_method_call start, method_name: ReleaseLight
[ 101.777255] iio-proxy: client_release start
[ 101.777351] iio-proxy: handle_generic_method_call end, method_name: ReleaseLight
[ 101.777356] iio-proxy: handle_method_call end, method_name: ReleaseLight
[ 101.777373] iio-proxy: poll_orientation start
[ 101.777377] iio-proxy: sysfs_get_int start
[ 101.777387] iio-proxy: sysfs_get_int going to get /sys/devices/pci0000:00/0000:00:15.0/i2c_designware.0/i2c-7/i2c-SMO8840:00/iio:device0/in_accel_x_raw contents
[ 101.778165] Method call test end
dmesg-to-upstream.txt
The dbus method call "ReleaseLight" is pended and waiting for poll_orientation
finished in main event loop.
poll_orientation
will read the 3 axes of the accelerometer by calling sysfs_get_int
3 times. sysfs_get_int
takes more than 2 seconds for reading the file each time. So, poll_orientation
takes almost 7 seconds for blocking exection.
The IO blocks the single thread main event loop.