Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8aa7e847 authored by Jens Axboe's avatar Jens Axboe Committed by Jens Axboe
Browse files

Fix congestion_wait() sync/async vs read/write confusion



Commit 1faa16d2 accidentally broke
the bdi congestion wait queue logic, causing us to wait on congestion
for WRITE (== 1) when we really wanted BLK_RW_ASYNC (== 0) instead.

Signed-off-by: default avatarJens Axboe <jens.axboe@oracle.com>
parent c2cc49a2
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -751,7 +751,7 @@ unsigned long __copy_to_user_ll(void __user *to, const void *from,

			if (retval == -ENOMEM && is_global_init(current)) {
				up_read(&current->mm->mmap_sem);
				congestion_wait(WRITE, HZ/50);
				congestion_wait(BLK_RW_ASYNC, HZ/50);
				goto survive;
			}

+6 −4
Original line number Diff line number Diff line
@@ -1372,8 +1372,10 @@ static int pkt_handle_queue(struct pktcdvd_device *pd)
	wakeup = (pd->write_congestion_on > 0
	 		&& pd->bio_queue_size <= pd->write_congestion_off);
	spin_unlock(&pd->lock);
	if (wakeup)
		clear_bdi_congested(&pd->disk->queue->backing_dev_info, WRITE);
	if (wakeup) {
		clear_bdi_congested(&pd->disk->queue->backing_dev_info,
					BLK_RW_ASYNC);
	}

	pkt->sleep_time = max(PACKET_WAIT_TIME, 1);
	pkt_set_state(pkt, PACKET_WAITING_STATE);
@@ -2592,10 +2594,10 @@ static int pkt_make_request(struct request_queue *q, struct bio *bio)
	spin_lock(&pd->lock);
	if (pd->write_congestion_on > 0
	    && pd->bio_queue_size >= pd->write_congestion_on) {
		set_bdi_congested(&q->backing_dev_info, WRITE);
		set_bdi_congested(&q->backing_dev_info, BLK_RW_ASYNC);
		do {
			spin_unlock(&pd->lock);
			congestion_wait(WRITE, HZ);
			congestion_wait(BLK_RW_ASYNC, HZ);
			spin_lock(&pd->lock);
		} while(pd->bio_queue_size > pd->write_congestion_off);
	}
+1 −1
Original line number Diff line number Diff line
@@ -776,7 +776,7 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io)
		 * But don't wait if split was due to the io size restriction
		 */
		if (unlikely(out_of_pages))
			congestion_wait(WRITE, HZ/100);
			congestion_wait(BLK_RW_ASYNC, HZ/100);

		/*
		 * With async crypto it is unsafe to share the crypto context
+1 −1
Original line number Diff line number Diff line
@@ -134,7 +134,7 @@ static int fat_file_release(struct inode *inode, struct file *filp)
	if ((filp->f_mode & FMODE_WRITE) &&
	     MSDOS_SB(inode->i_sb)->options.flush) {
		fat_flush_inodes(inode->i_sb, inode, NULL);
		congestion_wait(WRITE, HZ/10);
		congestion_wait(BLK_RW_ASYNC, HZ/10);
	}
	return 0;
}
+4 −4
Original line number Diff line number Diff line
@@ -286,8 +286,8 @@ __releases(&fc->lock)
		}
		if (fc->num_background == FUSE_CONGESTION_THRESHOLD &&
		    fc->connected && fc->bdi_initialized) {
			clear_bdi_congested(&fc->bdi, READ);
			clear_bdi_congested(&fc->bdi, WRITE);
			clear_bdi_congested(&fc->bdi, BLK_RW_SYNC);
			clear_bdi_congested(&fc->bdi, BLK_RW_ASYNC);
		}
		fc->num_background--;
		fc->active_background--;
@@ -414,8 +414,8 @@ static void fuse_request_send_nowait_locked(struct fuse_conn *fc,
		fc->blocked = 1;
	if (fc->num_background == FUSE_CONGESTION_THRESHOLD &&
	    fc->bdi_initialized) {
		set_bdi_congested(&fc->bdi, READ);
		set_bdi_congested(&fc->bdi, WRITE);
		set_bdi_congested(&fc->bdi, BLK_RW_SYNC);
		set_bdi_congested(&fc->bdi, BLK_RW_ASYNC);
	}
	list_add_tail(&req->list, &fc->bg_queue);
	flush_bg_queue(fc);
Loading