Re: [PATCH v3] Input: evdev - Flush queues during EVIOCGKEY-like ioctls

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Dmitry

On Thu, Jun 6, 2013 at 9:15 PM, Dmitry Torokhov
<dmitry.torokhov@xxxxxxxxx> wrote:
> Hi David,
>
> On Thu, Mar 28, 2013 at 12:59:40PM +0100, David Herrmann wrote:
>> If userspace requests current KEY-state, they very likely assume that no
>> such events are pending in the output queue of the evdev device.
>> Otherwise, they will parse events which they already handled via
>> EVIOCGKEY(). For XKB applications this can cause irreversible keyboard
>> states if a modifier is locked multiple times because a CTRL-DOWN event is
>> handled once via EVIOCGKEY() and once from the queue via read(), even
>> though it should handle it only once.
>>
>> Therefore, lets do the only logical thing and flush the evdev queue
>> atomically during this ioctl. We only flush events that are affected by
>> the given ioctl.
>>
>> This only affects boolean events like KEY, SND, SW and LED. ABS, REL and
>> others are not affected as duplicate events can be handled gracefully by
>> user-space.
>>
>> Note: This actually breaks semantics of the evdev ABI. However,
>> investigations showed that userspace already expects the new semantics and
>> we end up fixing at least all XKB applications.
>> All applications that are aware of this race-condition mirror the KEY
>> state for each open-file and detect/drop duplicate events. Hence, they do
>> not care whether duplicates are posted or not and work fine with this fix.
>>
>> Also note that we need proper locking to guarantee atomicity and avoid
>> dead-locks. event_lock must be locked before queue_lock (see input-core).
>> However, we can safely release event_lock while flushing the queue. This
>> allows the input-core to proceed with pending events and only stop if it
>> needs our queue_lock to post new events.
>> This should guarantee that we don't block event-dispatching for too long
>> while flushing a single event queue.
>
> Could you please tell me again why we need to take event_lock in
> addition to buffer_lock? We only affect the state of one client's buffer
> and it seems to be that event_lock alone should be enough. At least it
> is enough in read() when we fetching events form the client's queue.

We need the buffer_lock to protect against evdev_fetch_next_event() as
we might modify any part of the buffer in __flush_queue(). We don't
want userspace to get inconsistent data. And we need event_lock to
protect:
  memcpy(mem, bits, sizeof(unsigned long) * max);
Otherwise, input-core might modify the event-bits while we copy them
to our buffer. But we want the function to be atomic, so we cannot
allow modifications during the function-call.

Regards
David
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux