patch "bus: mhi: ep: Change state_lock to mutex" added to char-misc-next
Subsystems (2)
This is a note to let you know that I've just added the patch titled
bus: mhi: ep: Change state_lock to mutex
to my char-misc git tree which can be found at
git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git
in the char-misc-next branch.
The patch will show up in the next release of the linux-next tree (usually sometime within the next 24 hours during the week.)
The patch will also be merged in the next major kernel release during the merge window.
If you have any questions about this process, please let me know.
From 1ddc7618294084fff8d673217a9479550990ee84 Mon Sep 17 00:00:00 2001
From: Manivannan Sadhasivam <[email protected]>
Date: Mon, 23 Jan 2023 12:59:45 +0530
Subject: bus: mhi: ep: Change state_lock to mutex
state_lock, the spinlock type is meant to protect race against concurrent MHI state transitions. In mhi_ep_set_m0_state(), while the state_lock is being held, the channels are resumed in mhi_ep_resume_channels() if the previous state was M3. This causes sleeping in atomic bug, since mhi_ep_resume_channels() use mutex internally.
Since the state_lock is supposed to be held throughout the state change, it is not ideal to drop the lock before calling mhi_ep_resume_channels(). So to fix this issue, let's change the type of state_lock to mutex. This would also allow holding the lock throughout all state transitions thereby avoiding any potential race.
--- drivers/bus/mhi/ep/main.c | 8 +++++--- drivers/bus/mhi/ep/sm.c | 42 ++++++++++++++++++++++----------------- include/linux/mhi_ep.h | 4 ++-- 3 files changed, 31 insertions(+), 23 deletions(-)
drivers/bus/mhi/ep/main.c +5 -3
@@ -1001,11 +1001,11 @@ static void mhi_ep_reset_worker(struct work_struct *work)mhi_ep_power_down (mhi_cntrl); -spin_lock_bh (&mhi_cntrl->state_lock); +mutex_lock (&mhi_cntrl->state_lock); +/* Reset MMIO to signal host that the MHI_RESET is completed in endpoint */ mhi_ep_mmio_reset (mhi_cntrl); cur_state = mhi_cntrl->mhi_state; -spin_unlock_bh (&mhi_cntrl->state_lock);/* * Only proceed further if the reset is due to SYS_ERR. The host will
@@ -1014,6 +1014,8 @@ static void mhi_ep_reset_worker(struct work_struct *work)*/ if (cur_state ==MHI_STATE_SYS_ERR )mhi_ep_power_up (mhi_cntrl); + +mutex_unlock (&mhi_cntrl->state_lock); }/*
@@ -1386,8 +1388,8 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl,INIT_LIST_HEAD (&mhi_cntrl->st_transition_list);INIT_LIST_HEAD (&mhi_cntrl->ch_db_list); -spin_lock_init (&mhi_cntrl->state_lock);spin_lock_init (&mhi_cntrl->list_lock); +mutex_init (&mhi_cntrl->state_lock);mutex_init (&mhi_cntrl->event_lock);/* Set MHI version and AMSS EE before enumeration */
drivers/bus/mhi/ep/sm.c +24 -18
104 lines not on this page · raw message
include/linux/mhi_ep.h +2 -2
@@ -70,8 +70,8 @@ struct mhi_ep_db_info {* @cmd_ctx_cache_phys: Physical address of the host command context cache * @chdb: Array of channel doorbell interrupt info * @event_lock: Lock for protecting event rings -* @list_lock: Lock for protecting state transition and channel doorbell lists * @state_lock: Lock for protecting state transitions +* @list_lock: Lock for protecting state transition and channel doorbell lists * @st_transition_list: List of state transitions * @ch_db_list: List of queued channel doorbells * @wq: Dedicated workqueue for handling rings and state changes
@@ -117,8 +117,8 @@ struct mhi_ep_cntrl {struct mhi_ep_db_info chdb[4 ];struct mutex event_lock; +struct mutex state_lock;spinlock_t list_lock; -spinlock_t state_lock;struct list_head st_transition_list;struct list_head ch_db_list;
Signature · 1 line
2.39.1