diff options
author | Hans Verkuil <hverkuil-cisco@xs4all.nl> | 2021-11-24 11:38:57 +0100 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab+huawei@kernel.org> | 2021-11-30 12:22:09 +0100 |
commit | 2ddd03309433d39852945c2f85d36e796c558793 (patch) | |
tree | f384b343b973038d61ef1cb6b5cdf37387e290fb | |
parent | 1a59cd88f55068710f6549bee548846661673780 (diff) | |
download | linux-2ddd03309433d39852945c2f85d36e796c558793.tar.bz2 |
media: cec: safely unhook lists in cec_data
smatch warns about data->list not being removed from list:
drivers/media/cec/core/cec-adap.c:926 cec_transmit_msg_fh() warn: '&data->list' not removed from list
It is a false warning, but it doesn't hurt to make the code more robust
and safely unhook data->list and data->xfer_list together with a WARN_ON
if this is actually ever needed (this really shouldn't happen).
Note that fixing the data->list warning just replaced it with a new similar
warning for data->xfer_list, so both needed to be addressed.
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
-rw-r--r-- | drivers/media/cec/core/cec-adap.c | 8 | ||||
-rw-r--r-- | drivers/media/cec/core/cec-api.c | 2 |
2 files changed, 8 insertions, 2 deletions
diff --git a/drivers/media/cec/core/cec-adap.c b/drivers/media/cec/core/cec-adap.c index 79fa36de8a04..da73eb50cce2 100644 --- a/drivers/media/cec/core/cec-adap.c +++ b/drivers/media/cec/core/cec-adap.c @@ -342,7 +342,7 @@ static void cec_data_completed(struct cec_data *data) * Without that we would be referring to a closed filehandle. */ if (data->fh) - list_del(&data->xfer_list); + list_del_init(&data->xfer_list); if (data->blocking) { /* @@ -898,6 +898,8 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg, if (fh) list_add_tail(&data->xfer_list, &fh->xfer_list); + else + INIT_LIST_HEAD(&data->xfer_list); list_add_tail(&data->list, &adap->transmit_queue); adap->transmit_queue_sz++; @@ -923,6 +925,10 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg, /* The transmit completed (possibly with an error) */ *msg = data->msg; + if (WARN_ON(!list_empty(&data->list))) + list_del(&data->list); + if (WARN_ON(!list_empty(&data->xfer_list))) + list_del(&data->xfer_list); kfree(data); return 0; } diff --git a/drivers/media/cec/core/cec-api.c b/drivers/media/cec/core/cec-api.c index 769e6b4cddce..0edb7142afdb 100644 --- a/drivers/media/cec/core/cec-api.c +++ b/drivers/media/cec/core/cec-api.c @@ -669,7 +669,7 @@ static int cec_release(struct inode *inode, struct file *filp) data->blocking = false; data->fh = NULL; - list_del(&data->xfer_list); + list_del_init(&data->xfer_list); } mutex_unlock(&adap->lock); while (!list_empty(&fh->msgs)) { |