]> git.baikalelectronics.ru Git - kernel.git/commitdiff
media: cec-pin.c: don't zero work_pin_num_events in adap_enable
authorHans Verkuil <hverkuil-cisco@xs4all.nl>
Tue, 10 May 2022 11:59:48 +0000 (13:59 +0200)
committerMauro Carvalho Chehab <mchehab@kernel.org>
Fri, 13 May 2022 09:27:47 +0000 (11:27 +0200)
It's OK to keep the pending pin events when disabling or
enabling the 'adapter'. Zeroing this can cause a race condition
if this happens when the pin kthread is handling a pin event
and calls atomic_dec later, causing work_pin_num_events to become
negative.

Just leave pending events in the queue, they'll be read eventually.

Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
drivers/media/cec/core/cec-pin.c

index 4bd7be4e2edfedf1fd598f14886a82a68bd8cd03..68353c5dc5019383f9abe814ca8578bd1232b7dc 100644 (file)
@@ -1123,9 +1123,6 @@ static int cec_pin_adap_enable(struct cec_adapter *adap, bool enable)
        struct cec_pin *pin = adap->pin;
 
        if (enable) {
-               atomic_set(&pin->work_pin_num_events, 0);
-               pin->work_pin_events_rd = pin->work_pin_events_wr = 0;
-               pin->work_pin_events_dropped = false;
                cec_pin_read(pin);
                cec_pin_to_idle(pin);
                pin->tx_msg.len = 0;
@@ -1150,7 +1147,6 @@ static int cec_pin_adap_enable(struct cec_adapter *adap, bool enable)
                cec_pin_to_idle(pin);
                pin->state = CEC_ST_OFF;
                pin->work_tx_status = 0;
-               atomic_set(&pin->work_pin_num_events, 0);
                atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_DISABLE);
                wake_up_interruptible(&pin->kthread_waitq);
        }
@@ -1338,6 +1334,7 @@ struct cec_adapter *cec_pin_allocate_adapter(const struct cec_pin_ops *pin_ops,
                return ERR_PTR(-ENOMEM);
        pin->ops = pin_ops;
        hrtimer_init(&pin->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+       atomic_set(&pin->work_pin_num_events, 0);
        pin->timer.function = cec_pin_timer;
        init_waitqueue_head(&pin->kthread_waitq);
        pin->tx_custom_low_usecs = CEC_TIM_CUSTOM_DEFAULT;