From: Xiao Yang <yangx.jy@cn.fujitsu.com>
To: ltp@lists.linux.it
Subject: [LTP] [PATCH v3] kernel/input: fix failure on an old kernel
Date: Mon, 4 Dec 2017 15:45:24 +0800 [thread overview]
Message-ID: <5A24FD14.90208@cn.fujitsu.com> (raw)
In-Reply-To: <1510555504-6103-1-git-send-email-yangx.jy@cn.fujitsu.com>
Hi Cyril,
Ping. :-)
Thanks,
Xiao Yang
On 2017/11/13 14:45, Xiao Yang wrote:
> 1) On some old kernels(e.g. v2.6.32), we always triggered the following
> error when running input04 and input05:
> --------------------------------------------------------------------
> TINFO : Found uinput dev at /dev/uinput
> TINFO : Unexpected ev type=0 code=0 value=0
> TFAIL : Data received /dev/inputX
> ---------------------------------------------------------------------
>
> After investigation, the single EV_SYN event can be processed on an
> old kernel. However, the EV_SYN event handling has been modfied by
> the following patch:
> '4369c64c79a2("Input: Send events one packet at a time")'
>
> The patch is designed to reduce the time taken for processing a lot of
> events. As a side effect, the single EV_SYN event handling depends on
> one or more other events(e.g. EV_REL), so it should be processed
> together with others, since this action is atomic.
>
> Only when the number of queued events(include EV_SYN) is greater than
> one can these events be processed.
> Please see the kenrel code in drivers/input/input.c, as below:
> --------------------------------------------------------------------
> static void input_handle_event(struct input_dev *dev,
> ...
> if (disposition& INPUT_FLUSH) {
> // num_vals: number of values queued in the current frame
> if (dev->num_vals>= 2)
> input_pass_values(dev, dev->vals, dev->num_vals);
> dev->num_vals = 0;
> ...
> --------------------------------------------------------------------
>
> For example, steps to send an empty move and EV_SYN:
> -----------------------------------------------------
> send_event(fd, EV_REL, REL_X, 0);
> send_event(fd, EV_SYN, 0, 0);
> -----------------------------------------------------
>
> On an old kernel(before v3.7.0), the EV_SYN/SYN_REPORT event can be
> processed independently, so it is passed into /dev/input/eventX.
>
> On a new kernel(since v3.7.0), the EV_SYN/SYN_REPORT event depends on
> EV_REL/REL_X which is an empty move, so it is ignored.
>
> We feel this failure is due to the different mechanism of processing
> EV_SYN instead of a kernel bug, so we ignore stray sync events on older
> kernels.
>
> 2) We move the check_event_code and check_sync_event() helpers to the
> library so that we can use them.
>
> 3) Fix compiler warning, as below:
> ------------------------------------------------------------------------
> input06.c:213: warning: ‘ret’ may be used uninitialized in this function
> ------------------------------------------------------------------------
>
> Signed-off-by: Xiao Yang<yangx.jy@cn.fujitsu.com>
> ---
> testcases/kernel/input/input02.c | 2 +-
> testcases/kernel/input/input04.c | 2 +-
> testcases/kernel/input/input05.c | 2 +-
> testcases/kernel/input/input06.c | 18 ++++--------------
> testcases/kernel/input/input_helper.c | 34 +++++++++++++++++++++++++++++-----
> testcases/kernel/input/input_helper.h | 4 +++-
> 6 files changed, 39 insertions(+), 23 deletions(-)
>
> diff --git a/testcases/kernel/input/input02.c b/testcases/kernel/input/input02.c
> index df3b257..6964ed7 100644
> --- a/testcases/kernel/input/input02.c
> +++ b/testcases/kernel/input/input02.c
> @@ -61,7 +61,7 @@ int main(int ac, char **av)
> case -1:
> tst_brkm(TBROK | TERRNO, cleanup, "fork() failed");
> default:
> - if (no_events_queued(fd2))
> + if (no_events_queued(fd2, 0))
> tst_resm(TPASS, "No data received in eventX");
> else
> tst_resm(TFAIL, "Data received in eventX");
> diff --git a/testcases/kernel/input/input04.c b/testcases/kernel/input/input04.c
> index 4b16ca7..e57b76b 100644
> --- a/testcases/kernel/input/input04.c
> +++ b/testcases/kernel/input/input04.c
> @@ -57,7 +57,7 @@ int main(int ac, char **av)
> case -1:
> tst_brkm(TBROK | TERRNO, cleanup, "fork() failed");
> default:
> - if (no_events_queued(fd2))
> + if (no_events_queued(fd2, 1))
> tst_resm(TPASS,
> "No data received in /dev/inputX");
> else
> diff --git a/testcases/kernel/input/input05.c b/testcases/kernel/input/input05.c
> index 5ca01d8..46b4fe8 100644
> --- a/testcases/kernel/input/input05.c
> +++ b/testcases/kernel/input/input05.c
> @@ -63,7 +63,7 @@ int main(int ac, char **av)
> case -1:
> tst_brkm(TBROK | TERRNO, cleanup, "fork() failed");
> default:
> - if (no_events_queued(fd2))
> + if (no_events_queued(fd2, 1))
> tst_resm(TPASS, "No data received in eventX");
> else
> tst_resm(TFAIL, "Data received in eventX");
> diff --git a/testcases/kernel/input/input06.c b/testcases/kernel/input/input06.c
> index 4c5f1a8..14141b7 100644
> --- a/testcases/kernel/input/input06.c
> +++ b/testcases/kernel/input/input06.c
> @@ -115,11 +115,6 @@ static int check_event(struct input_event *iev, int event, int code, int value)
> return iev->type == event&& iev->code == code&& iev->value == value;
> }
>
> -static int check_event_code(struct input_event *iev, int event, int code)
> -{
> - return iev->type == event&& iev->code == code;
> -}
> -
> static void read_events(void)
> {
> int rd = read(fd2, events, sizeof(events));
> @@ -151,11 +146,6 @@ static struct input_event *next_event(void)
> return&events[ev_iter++];
> }
>
> -static int check_sync_event(void)
> -{
> - return check_event_code(next_event(), EV_SYN, SYN_REPORT);
> -}
> -
> static int parse_autorepeat_config(struct input_event *iev)
> {
> if (!check_event_code(iev, EV_REP, REP_DELAY)) {
> @@ -177,13 +167,13 @@ static int parse_key(struct input_event *iev)
> {
> int autorep_count = 0;
>
> - if (!check_event(iev, EV_KEY, KEY_X, 1) || !check_sync_event()) {
> + if (!check_event(iev, EV_KEY, KEY_X, 1) || !check_sync_event(next_event())) {
> tst_resm(TFAIL, "Didn't get expected key press for KEY_X");
> return 0;
> }
>
> iev = next_event();
> - while (check_event(iev, EV_KEY, KEY_X, 2)&& check_sync_event()) {
> + while (check_event(iev, EV_KEY, KEY_X, 2)&& check_sync_event(next_event())) {
> autorep_count++;
> iev = next_event();
> }
> @@ -195,7 +185,7 @@ static int parse_key(struct input_event *iev)
> return 0;
> }
>
> - if (!check_event(iev, EV_KEY, KEY_X, 0) || !check_sync_event()) {
> + if (!check_event(iev, EV_KEY, KEY_X, 0) || !check_sync_event(next_event())) {
> tst_resm(TFAIL,
> "Didn't get expected key release for KEY_X");
> return 0;
> @@ -210,7 +200,7 @@ static int parse_key(struct input_event *iev)
> static int check_events(void)
> {
> struct input_event *iev;
> - int ret;
> + int ret = 0;
> int rep_config_done = 0;
> int rep_keys_done = 0;
>
> diff --git a/testcases/kernel/input/input_helper.c b/testcases/kernel/input/input_helper.c
> index 08fa81c..13a6cd8 100644
> --- a/testcases/kernel/input/input_helper.c
> +++ b/testcases/kernel/input/input_helper.c
> @@ -229,21 +229,45 @@ void destroy_device(int fd)
> unload_uinput();
> }
>
> -int no_events_queued(int fd)
> +int check_event_code(struct input_event *iev, int event, int code)
> +{
> + return iev->type == event&& iev->code == code;
> +}
> +
> +int check_sync_event(struct input_event *iev)
> +{
> + return check_event_code(iev, EV_SYN, SYN_REPORT);
> +}
> +
> +/*
> + * the value of stray_sync_event:
> + * 0: EV_SYN/SYN_REPORT events should not be received in /dev/input/eventX
> + * 1: EV_SYN/SYN_REPORT events may be received in /dev/input/eventX
> + * On an old kernel(before v3.7.0), EV_SYN/SYN_REPORT events are always
> + * received even though we send empty moves.
> + */
> +int no_events_queued(int fd, int stray_sync_event)
> {
> struct pollfd fds = {.fd = fd, .events = POLLIN};
> - int ret, res;
> + int ret, res, sync_event_ignored;
> struct input_event ev;
>
> + if (tst_kvercmp(3, 7, 0)< 0&& stray_sync_event)
> + sync_event_ignored = 1;
> +
> ret = poll(&fds, 1, 30);
>
> if (ret> 0) {
> res = read(fd,&ev, sizeof(ev));
>
> if (res == sizeof(ev)) {
> - tst_resm(TINFO,
> - "Unexpected ev type=%i code=%i value=%i",
> - ev.type, ev.code, ev.value);
> + if (sync_event_ignored&& check_sync_event(&ev)) {
> + ret = 0;
> + } else {
> + tst_resm(TINFO,
> + "Unexpected ev type=%i code=%i value=%i",
> + ev.type, ev.code, ev.value);
> + }
> }
> }
>
> diff --git a/testcases/kernel/input/input_helper.h b/testcases/kernel/input/input_helper.h
> index 9b85dc9..7f61be1 100644
> --- a/testcases/kernel/input/input_helper.h
> +++ b/testcases/kernel/input/input_helper.h
> @@ -29,6 +29,8 @@ int open_uinput(void);
> void create_device(int fd);
> void setup_mouse_events(int fd);
> void destroy_device(int fd);
> -int no_events_queued(int fd);
> +int check_event_code(struct input_event *iev, int event, int code);
> +int check_sync_event(struct input_event *iev);
> +int no_events_queued(int fd, int stray_sync_event);
>
> #endif /* INPUT_HELPER_H */
next prev parent reply other threads:[~2017-12-04 7:45 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-10-09 9:57 [LTP] [PATCH] kernel/input: fix failure on an old kernel Xiao Yang
2017-11-06 7:52 ` Xiao Yang
2017-11-07 14:20 ` Cyril Hrubis
2017-11-08 10:37 ` [LTP] [PATCH v2] " Xiao Yang
2017-11-09 13:45 ` Cyril Hrubis
2017-11-13 6:45 ` [LTP] [PATCH v3] " Xiao Yang
2017-12-04 7:45 ` Xiao Yang [this message]
2017-12-04 15:33 ` Cyril Hrubis
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5A24FD14.90208@cn.fujitsu.com \
--to=yangx.jy@cn.fujitsu.com \
--cc=ltp@lists.linux.it \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.