Thread (3 messages) 3 messages, 3 authors, 2015-01-05

Re: [PATCH] Input: Optimize input_to_handler and input_pass_values function

From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Date: 2015-01-04 22:57:37

On Tue, Dec 30, 2014 at 11:19:53AM +0530, anshul.g@samsung.com wrote:
From: Anshul Garg <redacted>

As input_pass_values function is called everytime when EV_SYN is sent from
input driver or input event buffer becomes full.

1. In case of regular handler, event filter code should not run so added check 
   whether handler supports filter or not.
2. If input device doesn't support EV_KEY event type avoid running auto repeat code.
Can you please split it in 2 patches?
quoted hunk ↗ jump to hunk
Signed-off-by: Anshul Garg <redacted>
---
 drivers/input/input.c |   37 +++++++++++++++++++++----------------
 1 file changed, 21 insertions(+), 16 deletions(-)
diff --git a/drivers/input/input.c b/drivers/input/input.c
index bbec2dc..9d6609b 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -100,23 +100,24 @@ static unsigned int input_to_handler(struct input_handle *handle,
 	struct input_value *end = vals;
 	struct input_value *v;
 
-	for (v = vals; v != vals + count; v++) {
-		if (handler->filter &&
-		    handler->filter(handle, v->type, v->code, v->value))
-			continue;
-		if (end != v)
-			*end = *v;
-		end++;
+	if (handler->filter) {
+		for (v = vals; v != vals + count; v++) {
+			if (handler->filter(handle, v->type, v->code, v->value))
+				continue;
+			if (end != v)
+				*end = *v;
+			end++;
+		}
+		count = end - vals;
 	}
 
-	count = end - vals;
 	if (!count)
 		return 0;
 
 	if (handler->events)
 		handler->events(handle, vals, count);
 	else if (handler->event)
-		for (v = vals; v != end; v++)
+		for (v = vals; v != vals + count; v++)
 			handler->event(handle, v->type, v->code, v->value);
 
 	return count;
@@ -143,8 +144,10 @@ static void input_pass_values(struct input_dev *dev,
 		count = input_to_handler(handle, vals, count);
 	} else {
 		list_for_each_entry_rcu(handle, &dev->h_list, d_node)
-			if (handle->open)
+			if (handle->open && count)
 				count = input_to_handler(handle, vals, count);
+			else
+				break;
This is not correct. You'll stop delivering events at the very first
closed handle, which is not what we want. We need:

			if (handle->open) {
				count = input_to_handler(handle, vals, count);
				if (count == 0)
					break;
			}
quoted hunk ↗ jump to hunk
 	}
 
 	rcu_read_unlock();
@@ -152,12 +155,14 @@ static void input_pass_values(struct input_dev *dev,
 	add_input_randomness(vals->type, vals->code, vals->value);
 
 	/* trigger auto repeat for key events */
-	for (v = vals; v != vals + count; v++) {
-		if (v->type == EV_KEY && v->value != 2) {
-			if (v->value)
-				input_start_autorepeat(dev, v->code);
-			else
-				input_stop_autorepeat(dev);
+	if (test_bit(EV_KEY, dev->evbit)) {
You might want to test for presence of EV_REP as well.
+		for (v = vals; v != vals + count; v++) {
+			if (v->type == EV_KEY && v->value != 2) {
+				if (v->value)
+					input_start_autorepeat(dev, v->code);
+				else
+					input_stop_autorepeat(dev);
+			}
 		}
 	}
 }
-- 
1.7.9.5
Thanks.

-- 
Dmitry
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help