Revert "media: cec: fix a deadlock situation"

This reverts commit 0ab74ae99f which is
commit a9e6107616bb8108aa4fc22584a05e69761a91f7 upstream.

It breaks the Android kernel abi and can be brought back in the future
in an abi-safe way if it is really needed.

Bug: 161946584
Change-Id: I8abbf69a8f0812b07813ba1b94b5457d4fa27f7b
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman
2024-07-15 17:20:18 +00:00
parent 12d97237e4
commit e4f3376872
4 changed files with 19 additions and 39 deletions

View File

@@ -161,10 +161,10 @@ static void cec_queue_event(struct cec_adapter *adap,
u64 ts = ktime_get_ns();
struct cec_fh *fh;
mutex_lock(&adap->devnode.lock_fhs);
mutex_lock(&adap->devnode.lock);
list_for_each_entry(fh, &adap->devnode.fhs, list)
cec_queue_event_fh(fh, ev, ts);
mutex_unlock(&adap->devnode.lock_fhs);
mutex_unlock(&adap->devnode.lock);
}
/* Notify userspace that the CEC pin changed state at the given time. */
@@ -178,12 +178,11 @@ void cec_queue_pin_cec_event(struct cec_adapter *adap, bool is_high,
};
struct cec_fh *fh;
mutex_lock(&adap->devnode.lock_fhs);
list_for_each_entry(fh, &adap->devnode.fhs, list) {
mutex_lock(&adap->devnode.lock);
list_for_each_entry(fh, &adap->devnode.fhs, list)
if (fh->mode_follower == CEC_MODE_MONITOR_PIN)
cec_queue_event_fh(fh, &ev, ktime_to_ns(ts));
}
mutex_unlock(&adap->devnode.lock_fhs);
mutex_unlock(&adap->devnode.lock);
}
EXPORT_SYMBOL_GPL(cec_queue_pin_cec_event);
@@ -196,10 +195,10 @@ void cec_queue_pin_hpd_event(struct cec_adapter *adap, bool is_high, ktime_t ts)
};
struct cec_fh *fh;
mutex_lock(&adap->devnode.lock_fhs);
mutex_lock(&adap->devnode.lock);
list_for_each_entry(fh, &adap->devnode.fhs, list)
cec_queue_event_fh(fh, &ev, ktime_to_ns(ts));
mutex_unlock(&adap->devnode.lock_fhs);
mutex_unlock(&adap->devnode.lock);
}
EXPORT_SYMBOL_GPL(cec_queue_pin_hpd_event);
@@ -212,10 +211,10 @@ void cec_queue_pin_5v_event(struct cec_adapter *adap, bool is_high, ktime_t ts)
};
struct cec_fh *fh;
mutex_lock(&adap->devnode.lock_fhs);
mutex_lock(&adap->devnode.lock);
list_for_each_entry(fh, &adap->devnode.fhs, list)
cec_queue_event_fh(fh, &ev, ktime_to_ns(ts));
mutex_unlock(&adap->devnode.lock_fhs);
mutex_unlock(&adap->devnode.lock);
}
EXPORT_SYMBOL_GPL(cec_queue_pin_5v_event);
@@ -287,12 +286,12 @@ static void cec_queue_msg_monitor(struct cec_adapter *adap,
u32 monitor_mode = valid_la ? CEC_MODE_MONITOR :
CEC_MODE_MONITOR_ALL;
mutex_lock(&adap->devnode.lock_fhs);
mutex_lock(&adap->devnode.lock);
list_for_each_entry(fh, &adap->devnode.fhs, list) {
if (fh->mode_follower >= monitor_mode)
cec_queue_msg_fh(fh, msg);
}
mutex_unlock(&adap->devnode.lock_fhs);
mutex_unlock(&adap->devnode.lock);
}
/*
@@ -303,12 +302,12 @@ static void cec_queue_msg_followers(struct cec_adapter *adap,
{
struct cec_fh *fh;
mutex_lock(&adap->devnode.lock_fhs);
mutex_lock(&adap->devnode.lock);
list_for_each_entry(fh, &adap->devnode.fhs, list) {
if (fh->mode_follower == CEC_MODE_FOLLOWER)
cec_queue_msg_fh(fh, msg);
}
mutex_unlock(&adap->devnode.lock_fhs);
mutex_unlock(&adap->devnode.lock);
}
/* Notify userspace of an adapter state change. */
@@ -1560,7 +1559,6 @@ void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block)
/* Disabling monitor all mode should always succeed */
if (adap->monitor_all_cnt)
WARN_ON(call_op(adap, adap_monitor_all_enable, false));
/* serialize adap_enable */
mutex_lock(&adap->devnode.lock);
if (adap->needs_hpd || list_empty(&adap->devnode.fhs)) {
WARN_ON(adap->ops->adap_enable(adap, false));
@@ -1572,16 +1570,14 @@ void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block)
return;
}
/* serialize adap_enable */
mutex_lock(&adap->devnode.lock);
adap->last_initiator = 0xff;
adap->transmit_in_progress = false;
if (adap->needs_hpd || list_empty(&adap->devnode.fhs)) {
if (adap->ops->adap_enable(adap, true)) {
mutex_unlock(&adap->devnode.lock);
return;
}
if ((adap->needs_hpd || list_empty(&adap->devnode.fhs)) &&
adap->ops->adap_enable(adap, true)) {
mutex_unlock(&adap->devnode.lock);
return;
}
if (adap->monitor_all_cnt &&

View File

@@ -586,7 +586,6 @@ static int cec_open(struct inode *inode, struct file *filp)
return err;
}
/* serialize adap_enable */
mutex_lock(&devnode->lock);
if (list_empty(&devnode->fhs) &&
!adap->needs_hpd &&
@@ -625,9 +624,7 @@ static int cec_open(struct inode *inode, struct file *filp)
}
#endif
mutex_lock(&devnode->lock_fhs);
list_add(&fh->list, &devnode->fhs);
mutex_unlock(&devnode->lock_fhs);
mutex_unlock(&devnode->lock);
return 0;
@@ -656,11 +653,8 @@ static int cec_release(struct inode *inode, struct file *filp)
cec_monitor_all_cnt_dec(adap);
mutex_unlock(&adap->lock);
/* serialize adap_enable */
mutex_lock(&devnode->lock);
mutex_lock(&devnode->lock_fhs);
list_del(&fh->list);
mutex_unlock(&devnode->lock_fhs);
if (cec_is_registered(adap) && list_empty(&devnode->fhs) &&
!adap->needs_hpd && adap->phys_addr == CEC_PHYS_ADDR_INVALID) {
WARN_ON(adap->ops->adap_enable(adap, false));

View File

@@ -167,10 +167,8 @@ static void cec_devnode_unregister(struct cec_adapter *adap)
return;
}
mutex_lock(&devnode->lock_fhs);
list_for_each_entry(fh, &devnode->fhs, list)
wake_up_interruptible(&fh->wait);
mutex_unlock(&devnode->lock_fhs);
devnode->registered = false;
devnode->unregistered = true;
@@ -274,7 +272,6 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
/* adap->devnode initialization */
INIT_LIST_HEAD(&adap->devnode.fhs);
mutex_init(&adap->devnode.lock_fhs);
mutex_init(&adap->devnode.lock);
adap->kthread = kthread_run(cec_thread_func, adap, "cec-%s", name);

View File

@@ -26,17 +26,13 @@
* @dev: cec device
* @cdev: cec character device
* @minor: device node minor number
* @lock: lock to serialize open/release and registration
* @registered: the device was correctly registered
* @unregistered: the device was unregistered
* @lock_fhs: lock to control access to @fhs
* @fhs: the list of open filehandles (cec_fh)
* @lock: lock to control access to this structure
*
* This structure represents a cec-related device node.
*
* To add or remove filehandles from @fhs the @lock must be taken first,
* followed by @lock_fhs. It is safe to access @fhs if either lock is held.
*
* The @parent is a physical device. It must be set by core or device drivers
* before registering the node.
*/
@@ -47,13 +43,10 @@ struct cec_devnode {
/* device info */
int minor;
/* serialize open/release and registration */
struct mutex lock;
bool registered;
bool unregistered;
/* protect access to fhs */
struct mutex lock_fhs;
struct list_head fhs;
struct mutex lock;
};
struct cec_adapter;