diff options
| author | Gui-Dong Han <hanguidong02@gmail.com> | 2026-05-22 15:34:47 +0800 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2026-07-17 14:53:47 +0200 |
| commit | 7ddb521ab097413fbdff483b53b4a8c73a0e2b40 (patch) | |
| tree | 05e4d25b0b0f15b1bdd8255dc55976541aeb1d72 /drivers/gpib | |
| parent | 75f9481e0479c3faadf4d88baffe84b3d23d5763 (diff) | |
| download | linux-next-7ddb521ab097413fbdff483b53b4a8c73a0e2b40.tar.gz linux-next-7ddb521ab097413fbdff483b53b4a8c73a0e2b40.zip | |
gpib: Move stuck SRQ update under lock
Move the stuck SRQ state update into autopoll_all_devices() and keep it
under big_gpib_mutex. Except for initialization, keep the stuck_srq users
under this mutex.
autopoll_all_devices() is only called by autospoll_thread(), so there is
no need to return to autospoll_thread() and set this state after dropping
big_gpib_mutex.
Without the mutex, a newly opened device can clear stuck_srq and have
that clear overwritten by the previous autospoll result:
autospoll: serial_poll_all() returns 0 and unlocks big_gpib_mutex
open_dev_ioctl: open new device and clear stuck_srq
with big_gpib_mutex held
autospoll: set stuck_srq
That leaves the board marked stuck again after the new device is opened.
autospoll_wait_should_wake_up() then refuses to poll while stuck_srq is
set, so later SRQ handling can be mistakenly suppressed.
Without the mutex, atomic_set() and set_bit() only make individual
updates atomic. They do not order the two updates or make stuck_srq and
status visible as a consistent pair. Taking big_gpib_mutex serializes the
state transition with the other runtime users.
Keep the existing wakeup behavior unchanged and only move the stuck SRQ
state update under the mutex.
Fixes: 9dde4559e939 ("staging: gpib: Add GPIB common core driver")
Signed-off-by: Gui-Dong Han <hanguidong02@gmail.com>
Link: https://patch.msgid.link/20260522073447.4117690-1-hanguidong02@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/gpib')
| -rw-r--r-- | drivers/gpib/common/gpib_os.c | 21 | ||||
| -rw-r--r-- | drivers/gpib/common/iblib.c | 3 |
2 files changed, 11 insertions, 13 deletions
diff --git a/drivers/gpib/common/gpib_os.c b/drivers/gpib/common/gpib_os.c index 69f6aa73ab9a..384800e6bf97 100644 --- a/drivers/gpib/common/gpib_os.c +++ b/drivers/gpib/common/gpib_os.c @@ -289,18 +289,19 @@ int autopoll_all_devices(struct gpib_board *board) dev_dbg(board->gpib_dev, "autopoll has board lock\n"); retval = serial_poll_all(board, serial_timeout); - if (retval < 0) { - mutex_unlock(&board->big_gpib_mutex); - mutex_unlock(&board->user_mutex); - return retval; + if (retval >= 0) { + dev_dbg(board->gpib_dev, "complete\n"); + /* + * need to wake wait queue in case someone is + * waiting on RQS + */ + wake_up_interruptible(&board->wait); } - dev_dbg(board->gpib_dev, "complete\n"); - /* - * need to wake wait queue in case someone is - * waiting on RQS - */ - wake_up_interruptible(&board->wait); + if (retval <= 0) { + atomic_set(&board->stuck_srq, 1); + set_bit(SRQI_NUM, &board->status); + } mutex_unlock(&board->big_gpib_mutex); mutex_unlock(&board->user_mutex); diff --git a/drivers/gpib/common/iblib.c b/drivers/gpib/common/iblib.c index b672dd6aad25..511e1d61c1fb 100644 --- a/drivers/gpib/common/iblib.c +++ b/drivers/gpib/common/iblib.c @@ -193,9 +193,6 @@ static int autospoll_thread(void *board_void) } if (retval <= 0) { dev_err(board->gpib_dev, "stuck SRQ\n"); - - atomic_set(&board->stuck_srq, 1); // XXX could be better - set_bit(SRQI_NUM, &board->status); } } return retval; |
