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:
@@ -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 &&
|
||||
|
@@ -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));
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user