Skip to content

Commit cffc873

Browse files
Justin Sandersaxboe
authored andcommitted
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: Justin Sanders <[email protected]> Link: https://lore.kernel.org/r/[email protected] Tested-By: Valentin Kleibel <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 7f90d45 commit cffc873

File tree

3 files changed

+11
-3
lines changed

3 files changed

+11
-3
lines changed

drivers/block/aoe/aoe.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ enum {
8080
DEVFL_NEWSIZE = (1<<6), /* need to update dev size in block layer */
8181
DEVFL_FREEING = (1<<7), /* set when device is being cleaned up */
8282
DEVFL_FREED = (1<<8), /* device has been cleaned up */
83+
DEVFL_DEAD = (1<<9), /* device has timed out of aoe_deadsecs */
8384
};
8485

8586
enum {

drivers/block/aoe/aoecmd.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -754,7 +754,7 @@ rexmit_timer(struct timer_list *timer)
754754

755755
utgts = count_targets(d, NULL);
756756

757-
if (d->flags & DEVFL_TKILL) {
757+
if (d->flags & (DEVFL_TKILL | DEVFL_DEAD)) {
758758
spin_unlock_irqrestore(&d->lock, flags);
759759
return;
760760
}
@@ -786,7 +786,8 @@ rexmit_timer(struct timer_list *timer)
786786
* to clean up.
787787
*/
788788
list_splice(&flist, &d->factive[0]);
789-
aoedev_downdev(d);
789+
d->flags |= DEVFL_DEAD;
790+
queue_work(aoe_wq, &d->work);
790791
goto out;
791792
}
792793

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

902+
if (d->flags & DEVFL_DEAD)
903+
aoedev_downdev(d);
904+
901905
if (d->flags & DEVFL_GDALLOC)
902906
aoeblk_gdalloc(d);
903907

drivers/block/aoe/aoedev.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,11 @@ aoedev_downdev(struct aoedev *d)
200200
struct list_head *head, *pos, *nx;
201201
struct request *rq, *rqnext;
202202
int i;
203+
unsigned long flags;
203204

204-
d->flags &= ~DEVFL_UP;
205+
spin_lock_irqsave(&d->lock, flags);
206+
d->flags &= ~(DEVFL_UP | DEVFL_DEAD);
207+
spin_unlock_irqrestore(&d->lock, flags);
205208

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

0 commit comments

Comments
 (0)