Commit cffc873d authored by Justin Sanders's avatar Justin Sanders Committed by Jens Axboe
Browse files

aoe: defer rexmit timer downdev work to workqueue

When aoe's rexmit_timer() notices that an aoe target fails to respond to
commands for more than aoe_deadsecs, it calls aoedev_downdev() which
cleans the outstanding aoe and block queues. This can involve sleeping,
such as in blk_mq_freeze_queue(), which should not occur in irq context.

This patch defers that aoedev_downdev() call to the aoe device's
workqueue.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=212665


Signed-off-by: default avatarJustin Sanders <jsanders.devel@gmail.com>
Link: https://lore.kernel.org/r/20250610170600.869-2-jsanders.devel@gmail.com


Tested-By: default avatarValentin Kleibel <valentin@vrvis.at>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 7f90d45e
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -80,6 +80,7 @@ enum {
	DEVFL_NEWSIZE = (1<<6),	/* need to update dev size in block layer */
	DEVFL_FREEING = (1<<7),	/* set when device is being cleaned up */
	DEVFL_FREED = (1<<8),	/* device has been cleaned up */
	DEVFL_DEAD = (1<<9),	/* device has timed out of aoe_deadsecs */
};

enum {
+6 −2
Original line number Diff line number Diff line
@@ -754,7 +754,7 @@ rexmit_timer(struct timer_list *timer)

	utgts = count_targets(d, NULL);

	if (d->flags & DEVFL_TKILL) {
	if (d->flags & (DEVFL_TKILL | DEVFL_DEAD)) {
		spin_unlock_irqrestore(&d->lock, flags);
		return;
	}
@@ -786,7 +786,8 @@ rexmit_timer(struct timer_list *timer)
			 * to clean up.
			 */
			list_splice(&flist, &d->factive[0]);
			aoedev_downdev(d);
			d->flags |= DEVFL_DEAD;
			queue_work(aoe_wq, &d->work);
			goto out;
		}

@@ -898,6 +899,9 @@ aoecmd_sleepwork(struct work_struct *work)
{
	struct aoedev *d = container_of(work, struct aoedev, work);

	if (d->flags & DEVFL_DEAD)
		aoedev_downdev(d);

	if (d->flags & DEVFL_GDALLOC)
		aoeblk_gdalloc(d);

+4 −1
Original line number Diff line number Diff line
@@ -200,8 +200,11 @@ aoedev_downdev(struct aoedev *d)
	struct list_head *head, *pos, *nx;
	struct request *rq, *rqnext;
	int i;
	unsigned long flags;

	d->flags &= ~DEVFL_UP;
	spin_lock_irqsave(&d->lock, flags);
	d->flags &= ~(DEVFL_UP | DEVFL_DEAD);
	spin_unlock_irqrestore(&d->lock, flags);

	/* clean out active and to-be-retransmitted buffers */
	for (i = 0; i < NFACTIVE; i++) {