You need to sign in or sign up before continuing.
提交 b88c448d 编写于 作者: H Hans Verkuil 提交者: Yang Yingliang

media: cec: avoid decrementing transmit_queue_sz if it is 0

commit 95c29d46ab2a517e4c26d0a07300edca6768db17 upstream.

WARN if transmit_queue_sz is 0 but do not decrement it.
The CEC adapter will become unresponsive if it goes below
0 since then it thinks there are 4 billion messages in the
queue.

Obviously this should not happen, but a driver bug could
cause this.
Signed-off-by: NHans Verkuil <hverkuil-cisco@xs4all.nl>
Cc: <stable@vger.kernel.org>      # for v4.12 and up
Signed-off-by: NMauro Carvalho Chehab <mchehab+huawei@kernel.org>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 39ed20ef
...@@ -365,7 +365,8 @@ static void cec_data_cancel(struct cec_data *data, u8 tx_status) ...@@ -365,7 +365,8 @@ static void cec_data_cancel(struct cec_data *data, u8 tx_status)
} else { } else {
list_del_init(&data->list); list_del_init(&data->list);
if (!(data->msg.tx_status & CEC_TX_STATUS_OK)) if (!(data->msg.tx_status & CEC_TX_STATUS_OK))
data->adap->transmit_queue_sz--; if (!WARN_ON(!data->adap->transmit_queue_sz))
data->adap->transmit_queue_sz--;
} }
if (data->msg.tx_status & CEC_TX_STATUS_OK) { if (data->msg.tx_status & CEC_TX_STATUS_OK) {
...@@ -417,6 +418,14 @@ static void cec_flush(struct cec_adapter *adap) ...@@ -417,6 +418,14 @@ static void cec_flush(struct cec_adapter *adap)
* need to do anything special in that case. * need to do anything special in that case.
*/ */
} }
/*
* If something went wrong and this counter isn't what it should
* be, then this will reset it back to 0. Warn if it is not 0,
* since it indicates a bug, either in this framework or in a
* CEC driver.
*/
if (WARN_ON(adap->transmit_queue_sz))
adap->transmit_queue_sz = 0;
} }
/* /*
...@@ -507,7 +516,8 @@ int cec_thread_func(void *_adap) ...@@ -507,7 +516,8 @@ int cec_thread_func(void *_adap)
data = list_first_entry(&adap->transmit_queue, data = list_first_entry(&adap->transmit_queue,
struct cec_data, list); struct cec_data, list);
list_del_init(&data->list); list_del_init(&data->list);
adap->transmit_queue_sz--; if (!WARN_ON(!data->adap->transmit_queue_sz))
adap->transmit_queue_sz--;
/* Make this the current transmitting message */ /* Make this the current transmitting message */
adap->transmitting = data; adap->transmitting = data;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册