* uinput: ioctls for UI_BEGIN_FF_UPLOAD fails (returns -1). How to debug?
@ 2016-03-27 18:53 Manuel Reimer
2016-03-27 19:11 ` Clément VUCHENER
0 siblings, 1 reply; 9+ messages in thread
From: Manuel Reimer @ 2016-03-27 18:53 UTC (permalink / raw)
To: linux-input
Hello,
I'm writing on an usermode input driver.
Currently my force feedback support just consists of some printf's as a
first try.
My problem is, that it seems like as soon as I first sent something to
my open uinput device (some buttons that were pressed on the device) the
uinput backend seems to get into some bad state.
My "force feedback thread" gets the "EV_UINPUT" event trigger, but if I
try to call
ioctl(args->fduinput, UI_BEGIN_FF_UPLOAD, &upload);
in this case, then the return value is "-1"...
The same code works without any problem if no buttons are pressed and
"fftest" is called directly after startup of the driver application.
Can someone help me with debugging this problem? My understanding is,
that this call shouldn't return -1 if the "EV_UINPUT" event was
successfully received, right?
My system:
$ uname -a
Linux manuelspc 4.4.5-1-ARCH #1 SMP PREEMPT Thu Mar 10 07:38:19 CET 2016
x86_64 GNU/Linux
Thank you very much in advance.
Manuel
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: uinput: ioctls for UI_BEGIN_FF_UPLOAD fails (returns -1). How to debug?
2016-03-27 18:53 uinput: ioctls for UI_BEGIN_FF_UPLOAD fails (returns -1). How to debug? Manuel Reimer
@ 2016-03-27 19:11 ` Clément VUCHENER
2016-03-28 8:53 ` Manuel Reimer
0 siblings, 1 reply; 9+ messages in thread
From: Clément VUCHENER @ 2016-03-27 19:11 UTC (permalink / raw)
To: Manuel Reimer; +Cc: linux-input
2016-03-27 20:53 GMT+02:00 Manuel Reimer <mail+linux-input@m-reimer.de>:
> Hello,
>
> I'm writing on an usermode input driver.
>
> Currently my force feedback support just consists of some printf's as a
> first try.
>
> My problem is, that it seems like as soon as I first sent something to my
> open uinput device (some buttons that were pressed on the device) the uinput
> backend seems to get into some bad state.
>
> My "force feedback thread" gets the "EV_UINPUT" event trigger, but if I try
> to call
>
> ioctl(args->fduinput, UI_BEGIN_FF_UPLOAD, &upload);
>
> in this case, then the return value is "-1"...
Check the value of errno just after the failed call (and use strerror
to get a nice error message).
>
> The same code works without any problem if no buttons are pressed and
> "fftest" is called directly after startup of the driver application.
>
> Can someone help me with debugging this problem? My understanding is, that
> this call shouldn't return -1 if the "EV_UINPUT" event was successfully
> received, right?
You also need to check the event code, it must be UI_FF_UPLOAD.
>
> My system:
>
> $ uname -a
> Linux manuelspc 4.4.5-1-ARCH #1 SMP PREEMPT Thu Mar 10 07:38:19 CET 2016
> x86_64 GNU/Linux
>
> Thank you very much in advance.
>
> Manuel
> --
> To unsubscribe from this list: send the line "unsubscribe linux-input" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: uinput: ioctls for UI_BEGIN_FF_UPLOAD fails (returns -1). How to debug?
2016-03-27 19:11 ` Clément VUCHENER
@ 2016-03-28 8:53 ` Manuel Reimer
2016-03-29 10:21 ` Clément VUCHENER
0 siblings, 1 reply; 9+ messages in thread
From: Manuel Reimer @ 2016-03-28 8:53 UTC (permalink / raw)
To: Clément VUCHENER; +Cc: linux-input
On 03/27/2016 09:11 PM, Clément VUCHENER wrote:
> Check the value of errno just after the failed call (and use strerror
> to get a nice error message).
See the following output of my test program
UI_FF_UPLOAD start
UI_FF_UPLOAD middle
first ioctl failed -1 Inappropriate ioctl for device
second ioctl failed -1 Inappropriate ioctl for device
UI_FF_UPLOAD end
> You also need to check the event code, it must be UI_FF_UPLOAD.
else if (event.type == EV_UINPUT) {
printf("EV_UINPUT %d\n", event.code);
if (event.code == UI_FF_UPLOAD) {
printf("UI_FF_UPLOAD start\n");
struct uinput_ff_upload upload;
memset(&upload, 0, sizeof(upload));
upload.request_id = event.value;
printf("UI_FF_UPLOAD middle\n");
int ret;
ret = ioctl(args->fduinput, UI_BEGIN_FF_UPLOAD, &upload);
if (ret < 0) {
printf("first ioctl failed %d %s\n", ret, strerror(errno));
}
// Remember ID and motor values for playback
if (upload.effect.type == FF_RUMBLE) {
effect_id = upload.effect.id;
strong = upload.effect.u.rumble.strong_magnitude;
weak = upload.effect.u.rumble.weak_magnitude;
printf("Effect uploaded\n");
}
ret = ioctl(args->fduinput, UI_END_FF_UPLOAD, &upload);
if (ret < 0) {
printf("second ioctl failed %d %s\n", ret, strerror(errno));
}
printf("UI_FF_UPLOAD end\n");
}
else if (event.code == UI_FF_ERASE) {
struct uinput_ff_erase erase;
memset(&erase, 0, sizeof(erase));
erase.request_id = event.value;
// Doesn't make sense to actually erase something...
ioctl(args->fduinput, UI_BEGIN_FF_ERASE, &erase);
ioctl(args->fduinput, UI_END_FF_ERASE, &erase);
printf("Event erased\n");
}
}
I report that my device only supports one effect at once. My idea was
that I maybe try to get ff-memless connected to uinput at a later time
to make it emulate the common "memless configuration" used by the kernel
and operate my one-effect-rumble-only device.
The above code works well as long as nothing was sent out to the open
uinput file descriptor.
As soon as I press a button on my USB input device, it "wakes up" and
sends out information even if no button is pressed. This information is
also forwarded to uinput, so from this point on there is a regular
information stream from my code to the uinput module.
Maybe I have to add that I run dual-threaded. The above code is from my
"reception thread". The sending runs on a separate "sending thread".
Did I currently find out that uinput is not multithread-safe?
Manuel
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: uinput: ioctls for UI_BEGIN_FF_UPLOAD fails (returns -1). How to debug?
2016-03-28 8:53 ` Manuel Reimer
@ 2016-03-29 10:21 ` Clément VUCHENER
2016-03-29 16:48 ` Manuel Reimer
0 siblings, 1 reply; 9+ messages in thread
From: Clément VUCHENER @ 2016-03-29 10:21 UTC (permalink / raw)
To: Manuel Reimer; +Cc: linux-input
2016-03-28 10:53 GMT+02:00 Manuel Reimer <mail+linux-input@m-reimer.de>:
> On 03/27/2016 09:11 PM, Clément VUCHENER wrote:
>>
>> Check the value of errno just after the failed call (and use strerror
>> to get a nice error message).
>
>
> See the following output of my test program
>
>
> UI_FF_UPLOAD start
> UI_FF_UPLOAD middle
> first ioctl failed -1 Inappropriate ioctl for device
> second ioctl failed -1 Inappropriate ioctl for device
> UI_FF_UPLOAD end
>
>
>> You also need to check the event code, it must be UI_FF_UPLOAD.
>
>
>
> else if (event.type == EV_UINPUT) {
> printf("EV_UINPUT %d\n", event.code);
> if (event.code == UI_FF_UPLOAD) {
> printf("UI_FF_UPLOAD start\n");
> struct uinput_ff_upload upload;
> memset(&upload, 0, sizeof(upload));
>
> upload.request_id = event.value;
>
> printf("UI_FF_UPLOAD middle\n");mulitple
> int ret;
> ret = ioctl(args->fduinput, UI_BEGIN_FF_UPLOAD, &upload);
> if (ret < 0) {
> printf("first ioctl failed %d %s\n", ret, strerror(errno));
> }
>
> // Remember ID and motor values for playback
> if (upload.effect.type == FF_RUMBLE) {
> effect_id = upload.effect.id;
> strong = upload.effect.u.rumble.strong_magnitude;
> weak = upload.effect.u.rumble.weak_magnitude;
> printf("Effect uploaded\n");
> }
>
> ret = ioctl(args->fduinput, UI_END_FF_UPLOAD, &upload);
> if (ret < 0) {
> printf("second ioctl failed %d %s\n", ret, strerror(errno));
> }
> printf("UI_FF_UPLOAD end\n");
> }
> else if (event.code == UI_FF_ERASE) {
> struct uinput_ff_erase erase;
> memset(&erase, 0, sizeof(erase));
>
> erase.request_id = event.value;
>
> // Doesn't make sense to actually erase something...
> ioctl(args->fduinput, UI_BEGIN_FF_ERASE, &erase);
> ioctl(args->fduinput, UI_END_FF_ERASE, &erase);
> printf("Event erased\n");
> }
> }
>
This looks fine to me (maybe you should make sure upload.retval is
correctly set before calling UI_END_FF_UPLOAD, but that is not related
to your problem).
>
> I report that my device only supports one effect at once. My idea was that I
> maybe try to get ff-memless connected to uinput at a later time to make it
> emulate the common "memless configuration" used by the kernel and operate my
> one-effect-rumble-only device.
>
> The above code works well as long as nothing was sent out to the open uinput
> file descriptor.
>
> As soon as I press a button on my USB input device, it "wakes up" and sends
> out information even if no button is pressed. This information is also
> forwarded to uinput, so from this point on there is a regular information
> stream from my code to the uinput module.
>
> Maybe I have to add that I run dual-threaded. The above code is from my
> "reception thread". The sending runs on a separate "sending thread".
>
> Did I currently find out that uinput is not multithread-safe?
I am using uinput with multiple threads without problems (one in a
reading loop like yours, others writing events). You must be doing
something wrong with that file descriptor in that other thread.
>
> Manuel
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: uinput: ioctls for UI_BEGIN_FF_UPLOAD fails (returns -1). How to debug?
2016-03-29 10:21 ` Clément VUCHENER
@ 2016-03-29 16:48 ` Manuel Reimer
2016-03-31 17:46 ` Manuel Reimer
0 siblings, 1 reply; 9+ messages in thread
From: Manuel Reimer @ 2016-03-29 16:48 UTC (permalink / raw)
To: Clément VUCHENER; +Cc: linux-input
On 03/29/2016 12:21 PM, Clément VUCHENER wrote:
> This looks fine to me (maybe you should make sure upload.retval is
> correctly set before calling UI_END_FF_UPLOAD, but that is not related
> to your problem).
Thanks for the hint. I guess I should do that in the erase handler, too.
> I am using uinput with multiple threads without problems (one in a
> reading loop like yours, others writing events). You must be doing
> something wrong with that file descriptor in that other thread.
I also think so, but I don't see the mistake...
As the idea was to publish this under GPL3 anyway, I've uploaded my
early development state:
https://github.com/M-Reimer/pspaddrv
To give a short overview:
The relevant ones are:
device-handler.c
----------------
contains the actual handling thread functions
> DeviceHandlerThreadUSB
is called from main.c. Contains the "Sending main loop"
and starts a second thread in
> DeviceHandlerThreadRumble
which actually does the rumble stuff and contains the
"Receiving main loop"
uinput.c
--------
contains the uinput init function and the sending function which sends
one block of xbox button data at once without any prefiltering.
The code files, probably not relevant for this problem are:
main.c
------
starts the device handling threads (probably not relevant for my problems)
ps[34]-device.c
---------------
contain the gamepad interaction
usb.c
-----
some libusb helper functions
Would be great if someone could have a look at this and maybe give me a
hint about what could be the problem.
To test the code, an PS3 or PS4 gamepad is needed and the rumble stuff
actually needs to be commented out. If done so, this driver can be used
to emulate an XBox 360 gamepad with an PS3 or PS4 gamepad.
Thanks in advance
Manuel
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: uinput: ioctls for UI_BEGIN_FF_UPLOAD fails (returns -1). How to debug?
2016-03-29 16:48 ` Manuel Reimer
@ 2016-03-31 17:46 ` Manuel Reimer
2016-04-03 10:02 ` Manuel Reimer
0 siblings, 1 reply; 9+ messages in thread
From: Manuel Reimer @ 2016-03-31 17:46 UTC (permalink / raw)
To: linux-input
On 03/29/2016 06:48 PM, Manuel Reimer wrote:
> As the idea was to publish this under GPL3 anyway, I've uploaded my
> early development state:
>
> https://github.com/M-Reimer/pspaddrv
I'm still getting the errors and I'm still not finding any reason for them.
I had a look at the kernel code and there are mutex locks, so at least
it seems like it should be thread-safe.
So what I don't understand is, if there are any limitations with the
function "mutex_lock_interruptible" used by the kernel.
As I have a big list of "write" in here:
https://github.com/M-Reimer/pspaddrv/blob/master/uinput.c#L170
And this block is called at maximum speed the USB attached controller
can deliver. I guess there is a really good chance that this function is
hit between "EV_UINPUT" is received and my UI_BEGIN_FF_UPLOAD ioctl is
sent. Will this conflict in some way?
Of course, it is possible to prefilter the events, I plan to send to
uinput. I can keep a copy of the last sent event block and compare each
event to the old state before actually sending it. Is there any chance
that this could help in this case?
Thanks in advance
Manuel
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: uinput: ioctls for UI_BEGIN_FF_UPLOAD fails (returns -1). How to debug?
2016-03-31 17:46 ` Manuel Reimer
@ 2016-04-03 10:02 ` Manuel Reimer
2016-04-03 10:21 ` Clément VUCHENER
0 siblings, 1 reply; 9+ messages in thread
From: Manuel Reimer @ 2016-04-03 10:02 UTC (permalink / raw)
To: linux-input
On 03/31/2016 07:46 PM, Manuel Reimer wrote:
> On 03/29/2016 06:48 PM, Manuel Reimer wrote:
>> As the idea was to publish this under GPL3 anyway, I've uploaded my
>> early development state:
>>
>> https://github.com/M-Reimer/pspaddrv
>
> I'm still getting the errors and I'm still not finding any reason for them.
Sorry for the spam, but my hope is that someone may have some hint that
helps me to track this down.
To further narrow things down, I commented the following line:
https://github.com/M-Reimer/pspaddrv/blob/master/device-handler.c#L176
This means, that my code does no longer actually do any sending to uinput!
And.... I still have the same problem... :(
So in other words: As soon as the attached gamepad starts to send data
to my daemon, the uinput interaction on the same daemon somehow gets
influenced/completely blocked.
So the only explanation, I have for this, is that something wents really
wrong somewhere deeper in the kernel. Maybe something with libusb/uinput
in combination?
If the problem occurs, the system (I use a VM to not harm my main
system) doesn't shut down properly.
In dmesg, I found the following:
[ 30.782513] input: Microsoft X-Box 360 pad as
/devices/virtual/input/input9
[ 240.130071] INFO: task fftest:379 blocked for more than 120 seconds.
[ 240.381802] Tainted: G O 4.4.5-1-ARCH #1
[ 240.391841] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs"
disables this message.
[ 240.392592] fftest D ffff88003cda3ba8 0 379 371
0x00000000
[ 240.392596] ffff88003cda3ba8 ffff880037b84800 ffffffff81810500
ffff88003ce16040
[ 240.392598] ffff88003cda4000 ffff88003cda3d58 ffff88003cda3d50
0000000000000000
[ 240.392600] ffff88003ce16040 ffff88003cda3bc0 ffffffff815935ec
7fffffffffffffff
[ 240.392601] Call Trace:
[ 240.392608] [<ffffffff815935ec>] schedule+0x3c/0x90
[ 240.392611] [<ffffffff81596086>] schedule_timeout+0x1d6/0x260
[ 240.392613] [<ffffffff81592e7a>] ? __schedule+0x3aa/0xae0
[ 240.392615] [<ffffffff815941a2>] wait_for_common+0xc2/0x180
[ 240.392617] [<ffffffff810a0ae0>] ? wake_up_q+0x70/0x70
[ 240.392619] [<ffffffff8159427d>] wait_for_completion+0x1d/0x20
[ 240.392624] [<ffffffffa039f728>]
uinput_request_submit.part.0+0x98/0xb0 [uinput]
[ 240.392626] [<ffffffffa03a0595>] uinput_dev_upload_effect+0x55/0x80
[uinput]
[ 240.392629] [<ffffffff8142f4c1>] input_ff_upload+0x181/0x300
[ 240.392632] [<ffffffffa0324d6b>] evdev_ioctl_handler+0xa8b/0x1150
[evdev]
[ 240.392634] [<ffffffff813a0810>] ? n_tty_open+0xe0/0xe0
[ 240.392636] [<ffffffffa0325460>] evdev_ioctl+0x10/0x12 [evdev]
[ 240.392643] [<ffffffff811f3258>] do_vfs_ioctl+0x298/0x480
[ 240.392646] [<ffffffff811e1662>] ? vfs_write+0x152/0x1a0
[ 240.392648] [<ffffffff811f34b9>] SyS_ioctl+0x79/0x90
[ 240.392649] [<ffffffff815970ee>] entry_SYSCALL_64_fastpath+0x12/0x6d
[ 360.390898] INFO: task fftest:379 blocked for more than 120 seconds.
[ 360.406008] Tainted: G O 4.4.5-1-ARCH #1
[ 360.406629] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs"
disables this message.
[ 360.407664] fftest D ffff88003cda3ba8 0 379 371
0x00000000
[ 360.407668] ffff88003cda3ba8 ffff880037b84800 ffffffff81810500
ffff88003ce16040
[ 360.407670] ffff88003cda4000 ffff88003cda3d58 ffff88003cda3d50
0000000000000000
[ 360.407671] ffff88003ce16040 ffff88003cda3bc0 ffffffff815935ec
7fffffffffffffff
[ 360.407673] Call Trace:
[ 360.407692] [<ffffffff815935ec>] schedule+0x3c/0x90
[ 360.407694] [<ffffffff81596086>] schedule_timeout+0x1d6/0x260
[ 360.407696] [<ffffffff81592e7a>] ? __schedule+0x3aa/0xae0
[ 360.407698] [<ffffffff815941a2>] wait_for_common+0xc2/0x180
[ 360.407701] [<ffffffff810a0ae0>] ? wake_up_q+0x70/0x70
[ 360.407702] [<ffffffff8159427d>] wait_for_completion+0x1d/0x20
[ 360.407707] [<ffffffffa039f728>]
uinput_request_submit.part.0+0x98/0xb0 [uinput]
[ 360.407708] [<ffffffffa03a0595>] uinput_dev_upload_effect+0x55/0x80
[uinput]
[ 360.407711] [<ffffffff8142f4c1>] input_ff_upload+0x181/0x300
[ 360.407715] [<ffffffffa0324d6b>] evdev_ioctl_handler+0xa8b/0x1150
[evdev]
[ 360.407717] [<ffffffff813a0810>] ? n_tty_open+0xe0/0xe0
[ 360.407719] [<ffffffffa0325460>] evdev_ioctl+0x10/0x12 [evdev]
[ 360.407721] [<ffffffff811f3258>] do_vfs_ioctl+0x298/0x480
[ 360.407724] [<ffffffff811e1662>] ? vfs_write+0x152/0x1a0
[ 360.407725] [<ffffffff811f34b9>] SyS_ioctl+0x79/0x90
[ 360.407727] [<ffffffff815970ee>] entry_SYSCALL_64_fastpath+0x12/0x6d
Maybe someone can help to find the reason... To be honest, I start to
give up to get a proper input driver done with Linux... :( Every
attempt, so far, ended in the kernel hanging somehow...
Thank you very much in advance for any help.
Manuel
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: uinput: ioctls for UI_BEGIN_FF_UPLOAD fails (returns -1). How to debug?
2016-04-03 10:02 ` Manuel Reimer
@ 2016-04-03 10:21 ` Clément VUCHENER
2016-04-05 19:10 ` Manuel Reimer
0 siblings, 1 reply; 9+ messages in thread
From: Clément VUCHENER @ 2016-04-03 10:21 UTC (permalink / raw)
To: Manuel Reimer; +Cc: linux-input
2016-04-03 12:02 GMT+02:00 Manuel Reimer <mail+linux-input@m-reimer.de>:
> On 03/31/2016 07:46 PM, Manuel Reimer wrote:
>
>
> Sorry for the spam, but my hope is that someone may have some hint that
> helps me to track this down.
>
> To further narrow things down, I commented the following line:
> https://github.com/M-Reimer/pspaddrv/blob/master/device-handler.c#L176
>
> This means, that my code does no longer actually do any sending to uinput!
>
> And.... I still have the same problem... :(
>
At line 159 you are passing the address of a stack variable that is no
longer valid when leaving the "if (1)". So the content of rargs may be
overwritten by future stack variable like msg_out in the next loop.
Fix your memory management and you may find out you don't actually
have any problem with uinput.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: uinput: ioctls for UI_BEGIN_FF_UPLOAD fails (returns -1). How to debug?
2016-04-03 10:21 ` Clément VUCHENER
@ 2016-04-05 19:10 ` Manuel Reimer
0 siblings, 0 replies; 9+ messages in thread
From: Manuel Reimer @ 2016-04-05 19:10 UTC (permalink / raw)
To: Clément VUCHENER; +Cc: linux-input
On 04/03/2016 12:21 PM, Clément VUCHENER wrote:
> At line 159 you are passing the address of a stack variable that is no
> longer valid when leaving the "if (1)". So the content of rargs may be
> overwritten by future stack variable like msg_out in the next loop.
> Fix your memory management and you may find out you don't actually
> have any problem with uinput.
Exactly! This seems to have resolved my problem. I did several tries and
so far no more crashes.
https://github.com/M-Reimer/pspaddrv/commit/effbaae8
Thank you very much for finding this one! I don't think I would have
ever found that one and maybe had given up at last...
Now I can continue with some code cleanup, adding the rumble code for
PS4 and finally I'll have to find a way to get the common "emulated
events" for memoryless devices. One solution would be to try to get
ff_memless connected with uinput via kernel patch. I'll give that a try
first.
Manuel
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2016-04-05 19:10 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-03-27 18:53 uinput: ioctls for UI_BEGIN_FF_UPLOAD fails (returns -1). How to debug? Manuel Reimer
2016-03-27 19:11 ` Clément VUCHENER
2016-03-28 8:53 ` Manuel Reimer
2016-03-29 10:21 ` Clément VUCHENER
2016-03-29 16:48 ` Manuel Reimer
2016-03-31 17:46 ` Manuel Reimer
2016-04-03 10:02 ` Manuel Reimer
2016-04-03 10:21 ` Clément VUCHENER
2016-04-05 19:10 ` Manuel Reimer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).