mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-01 00:58:39 +02:00 
			
		
		
		
	Btrfs: delete the entire async bio submission framework
Now that we're not using btrfs_schedule_bio() anymore, delete all the code that supported it. Reviewed-by: Josef Bacik <josef@toxicpanda.com> Reviewed-by: Nikolay Borisov <nborisov@suse.com> Signed-off-by: Chris Mason <clm@fb.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
		
							parent
							
								
									08635bae0b
								
							
						
					
					
						commit
						ba8a9d0795
					
				
					 5 changed files with 1 additions and 235 deletions
				
			
		|  | @ -723,7 +723,6 @@ struct btrfs_fs_info { | ||||||
| 	struct btrfs_workqueue *endio_meta_write_workers; | 	struct btrfs_workqueue *endio_meta_write_workers; | ||||||
| 	struct btrfs_workqueue *endio_write_workers; | 	struct btrfs_workqueue *endio_write_workers; | ||||||
| 	struct btrfs_workqueue *endio_freespace_worker; | 	struct btrfs_workqueue *endio_freespace_worker; | ||||||
| 	struct btrfs_workqueue *submit_workers; |  | ||||||
| 	struct btrfs_workqueue *caching_workers; | 	struct btrfs_workqueue *caching_workers; | ||||||
| 	struct btrfs_workqueue *readahead_workers; | 	struct btrfs_workqueue *readahead_workers; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1989,7 +1989,6 @@ static void btrfs_stop_all_workers(struct btrfs_fs_info *fs_info) | ||||||
| 	btrfs_destroy_workqueue(fs_info->rmw_workers); | 	btrfs_destroy_workqueue(fs_info->rmw_workers); | ||||||
| 	btrfs_destroy_workqueue(fs_info->endio_write_workers); | 	btrfs_destroy_workqueue(fs_info->endio_write_workers); | ||||||
| 	btrfs_destroy_workqueue(fs_info->endio_freespace_worker); | 	btrfs_destroy_workqueue(fs_info->endio_freespace_worker); | ||||||
| 	btrfs_destroy_workqueue(fs_info->submit_workers); |  | ||||||
| 	btrfs_destroy_workqueue(fs_info->delayed_workers); | 	btrfs_destroy_workqueue(fs_info->delayed_workers); | ||||||
| 	btrfs_destroy_workqueue(fs_info->caching_workers); | 	btrfs_destroy_workqueue(fs_info->caching_workers); | ||||||
| 	btrfs_destroy_workqueue(fs_info->readahead_workers); | 	btrfs_destroy_workqueue(fs_info->readahead_workers); | ||||||
|  | @ -2154,16 +2153,6 @@ static int btrfs_init_workqueues(struct btrfs_fs_info *fs_info, | ||||||
| 	fs_info->caching_workers = | 	fs_info->caching_workers = | ||||||
| 		btrfs_alloc_workqueue(fs_info, "cache", flags, max_active, 0); | 		btrfs_alloc_workqueue(fs_info, "cache", flags, max_active, 0); | ||||||
| 
 | 
 | ||||||
| 	/*
 |  | ||||||
| 	 * a higher idle thresh on the submit workers makes it much more |  | ||||||
| 	 * likely that bios will be send down in a sane order to the |  | ||||||
| 	 * devices |  | ||||||
| 	 */ |  | ||||||
| 	fs_info->submit_workers = |  | ||||||
| 		btrfs_alloc_workqueue(fs_info, "submit", flags, |  | ||||||
| 				      min_t(u64, fs_devices->num_devices, |  | ||||||
| 					    max_active), 64); |  | ||||||
| 
 |  | ||||||
| 	fs_info->fixup_workers = | 	fs_info->fixup_workers = | ||||||
| 		btrfs_alloc_workqueue(fs_info, "fixup", flags, 1, 0); | 		btrfs_alloc_workqueue(fs_info, "fixup", flags, 1, 0); | ||||||
| 
 | 
 | ||||||
|  | @ -2202,7 +2191,7 @@ static int btrfs_init_workqueues(struct btrfs_fs_info *fs_info, | ||||||
| 		btrfs_alloc_workqueue(fs_info, "qgroup-rescan", flags, 1, 0); | 		btrfs_alloc_workqueue(fs_info, "qgroup-rescan", flags, 1, 0); | ||||||
| 
 | 
 | ||||||
| 	if (!(fs_info->workers && fs_info->delalloc_workers && | 	if (!(fs_info->workers && fs_info->delalloc_workers && | ||||||
| 	      fs_info->submit_workers && fs_info->flush_workers && | 	      fs_info->flush_workers && | ||||||
| 	      fs_info->endio_workers && fs_info->endio_meta_workers && | 	      fs_info->endio_workers && fs_info->endio_meta_workers && | ||||||
| 	      fs_info->endio_meta_write_workers && | 	      fs_info->endio_meta_write_workers && | ||||||
| 	      fs_info->endio_repair_workers && | 	      fs_info->endio_repair_workers && | ||||||
|  |  | ||||||
|  | @ -1669,7 +1669,6 @@ static void btrfs_resize_thread_pool(struct btrfs_fs_info *fs_info, | ||||||
| 
 | 
 | ||||||
| 	btrfs_workqueue_set_max(fs_info->workers, new_pool_size); | 	btrfs_workqueue_set_max(fs_info->workers, new_pool_size); | ||||||
| 	btrfs_workqueue_set_max(fs_info->delalloc_workers, new_pool_size); | 	btrfs_workqueue_set_max(fs_info->delalloc_workers, new_pool_size); | ||||||
| 	btrfs_workqueue_set_max(fs_info->submit_workers, new_pool_size); |  | ||||||
| 	btrfs_workqueue_set_max(fs_info->caching_workers, new_pool_size); | 	btrfs_workqueue_set_max(fs_info->caching_workers, new_pool_size); | ||||||
| 	btrfs_workqueue_set_max(fs_info->endio_workers, new_pool_size); | 	btrfs_workqueue_set_max(fs_info->endio_workers, new_pool_size); | ||||||
| 	btrfs_workqueue_set_max(fs_info->endio_meta_workers, new_pool_size); | 	btrfs_workqueue_set_max(fs_info->endio_meta_workers, new_pool_size); | ||||||
|  |  | ||||||
|  | @ -397,8 +397,6 @@ static struct btrfs_device *__alloc_device(void) | ||||||
| 	INIT_LIST_HEAD(&dev->dev_alloc_list); | 	INIT_LIST_HEAD(&dev->dev_alloc_list); | ||||||
| 	INIT_LIST_HEAD(&dev->post_commit_list); | 	INIT_LIST_HEAD(&dev->post_commit_list); | ||||||
| 
 | 
 | ||||||
| 	spin_lock_init(&dev->io_lock); |  | ||||||
| 
 |  | ||||||
| 	atomic_set(&dev->reada_in_flight, 0); | 	atomic_set(&dev->reada_in_flight, 0); | ||||||
| 	atomic_set(&dev->dev_stats_ccnt, 0); | 	atomic_set(&dev->dev_stats_ccnt, 0); | ||||||
| 	btrfs_device_data_ordered_init(dev); | 	btrfs_device_data_ordered_init(dev); | ||||||
|  | @ -501,212 +499,6 @@ btrfs_get_bdev_and_sb(const char *device_path, fmode_t flags, void *holder, | ||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void requeue_list(struct btrfs_pending_bios *pending_bios, |  | ||||||
| 			struct bio *head, struct bio *tail) |  | ||||||
| { |  | ||||||
| 
 |  | ||||||
| 	struct bio *old_head; |  | ||||||
| 
 |  | ||||||
| 	old_head = pending_bios->head; |  | ||||||
| 	pending_bios->head = head; |  | ||||||
| 	if (pending_bios->tail) |  | ||||||
| 		tail->bi_next = old_head; |  | ||||||
| 	else |  | ||||||
| 		pending_bios->tail = tail; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
|  * we try to collect pending bios for a device so we don't get a large |  | ||||||
|  * number of procs sending bios down to the same device.  This greatly |  | ||||||
|  * improves the schedulers ability to collect and merge the bios. |  | ||||||
|  * |  | ||||||
|  * But, it also turns into a long list of bios to process and that is sure |  | ||||||
|  * to eventually make the worker thread block.  The solution here is to |  | ||||||
|  * make some progress and then put this work struct back at the end of |  | ||||||
|  * the list if the block device is congested.  This way, multiple devices |  | ||||||
|  * can make progress from a single worker thread. |  | ||||||
|  */ |  | ||||||
| static noinline void run_scheduled_bios(struct btrfs_device *device) |  | ||||||
| { |  | ||||||
| 	struct btrfs_fs_info *fs_info = device->fs_info; |  | ||||||
| 	struct bio *pending; |  | ||||||
| 	struct backing_dev_info *bdi; |  | ||||||
| 	struct btrfs_pending_bios *pending_bios; |  | ||||||
| 	struct bio *tail; |  | ||||||
| 	struct bio *cur; |  | ||||||
| 	int again = 0; |  | ||||||
| 	unsigned long num_run; |  | ||||||
| 	unsigned long batch_run = 0; |  | ||||||
| 	unsigned long last_waited = 0; |  | ||||||
| 	int force_reg = 0; |  | ||||||
| 	int sync_pending = 0; |  | ||||||
| 	struct blk_plug plug; |  | ||||||
| 
 |  | ||||||
| 	/*
 |  | ||||||
| 	 * this function runs all the bios we've collected for |  | ||||||
| 	 * a particular device.  We don't want to wander off to |  | ||||||
| 	 * another device without first sending all of these down. |  | ||||||
| 	 * So, setup a plug here and finish it off before we return |  | ||||||
| 	 */ |  | ||||||
| 	blk_start_plug(&plug); |  | ||||||
| 
 |  | ||||||
| 	bdi = device->bdev->bd_bdi; |  | ||||||
| 
 |  | ||||||
| loop: |  | ||||||
| 	spin_lock(&device->io_lock); |  | ||||||
| 
 |  | ||||||
| loop_lock: |  | ||||||
| 	num_run = 0; |  | ||||||
| 
 |  | ||||||
| 	/* take all the bios off the list at once and process them
 |  | ||||||
| 	 * later on (without the lock held).  But, remember the |  | ||||||
| 	 * tail and other pointers so the bios can be properly reinserted |  | ||||||
| 	 * into the list if we hit congestion |  | ||||||
| 	 */ |  | ||||||
| 	if (!force_reg && device->pending_sync_bios.head) { |  | ||||||
| 		pending_bios = &device->pending_sync_bios; |  | ||||||
| 		force_reg = 1; |  | ||||||
| 	} else { |  | ||||||
| 		pending_bios = &device->pending_bios; |  | ||||||
| 		force_reg = 0; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	pending = pending_bios->head; |  | ||||||
| 	tail = pending_bios->tail; |  | ||||||
| 	WARN_ON(pending && !tail); |  | ||||||
| 
 |  | ||||||
| 	/*
 |  | ||||||
| 	 * if pending was null this time around, no bios need processing |  | ||||||
| 	 * at all and we can stop.  Otherwise it'll loop back up again |  | ||||||
| 	 * and do an additional check so no bios are missed. |  | ||||||
| 	 * |  | ||||||
| 	 * device->running_pending is used to synchronize with the |  | ||||||
| 	 * schedule_bio code. |  | ||||||
| 	 */ |  | ||||||
| 	if (device->pending_sync_bios.head == NULL && |  | ||||||
| 	    device->pending_bios.head == NULL) { |  | ||||||
| 		again = 0; |  | ||||||
| 		device->running_pending = 0; |  | ||||||
| 	} else { |  | ||||||
| 		again = 1; |  | ||||||
| 		device->running_pending = 1; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	pending_bios->head = NULL; |  | ||||||
| 	pending_bios->tail = NULL; |  | ||||||
| 
 |  | ||||||
| 	spin_unlock(&device->io_lock); |  | ||||||
| 
 |  | ||||||
| 	while (pending) { |  | ||||||
| 
 |  | ||||||
| 		rmb(); |  | ||||||
| 		/* we want to work on both lists, but do more bios on the
 |  | ||||||
| 		 * sync list than the regular list |  | ||||||
| 		 */ |  | ||||||
| 		if ((num_run > 32 && |  | ||||||
| 		    pending_bios != &device->pending_sync_bios && |  | ||||||
| 		    device->pending_sync_bios.head) || |  | ||||||
| 		   (num_run > 64 && pending_bios == &device->pending_sync_bios && |  | ||||||
| 		    device->pending_bios.head)) { |  | ||||||
| 			spin_lock(&device->io_lock); |  | ||||||
| 			requeue_list(pending_bios, pending, tail); |  | ||||||
| 			goto loop_lock; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		cur = pending; |  | ||||||
| 		pending = pending->bi_next; |  | ||||||
| 		cur->bi_next = NULL; |  | ||||||
| 
 |  | ||||||
| 		BUG_ON(atomic_read(&cur->__bi_cnt) == 0); |  | ||||||
| 
 |  | ||||||
| 		/*
 |  | ||||||
| 		 * if we're doing the sync list, record that our |  | ||||||
| 		 * plug has some sync requests on it |  | ||||||
| 		 * |  | ||||||
| 		 * If we're doing the regular list and there are |  | ||||||
| 		 * sync requests sitting around, unplug before |  | ||||||
| 		 * we add more |  | ||||||
| 		 */ |  | ||||||
| 		if (pending_bios == &device->pending_sync_bios) { |  | ||||||
| 			sync_pending = 1; |  | ||||||
| 		} else if (sync_pending) { |  | ||||||
| 			blk_finish_plug(&plug); |  | ||||||
| 			blk_start_plug(&plug); |  | ||||||
| 			sync_pending = 0; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		btrfsic_submit_bio(cur); |  | ||||||
| 		num_run++; |  | ||||||
| 		batch_run++; |  | ||||||
| 
 |  | ||||||
| 		cond_resched(); |  | ||||||
| 
 |  | ||||||
| 		/*
 |  | ||||||
| 		 * we made progress, there is more work to do and the bdi |  | ||||||
| 		 * is now congested.  Back off and let other work structs |  | ||||||
| 		 * run instead |  | ||||||
| 		 */ |  | ||||||
| 		if (pending && bdi_write_congested(bdi) && batch_run > 8 && |  | ||||||
| 		    fs_info->fs_devices->open_devices > 1) { |  | ||||||
| 			struct io_context *ioc; |  | ||||||
| 
 |  | ||||||
| 			ioc = current->io_context; |  | ||||||
| 
 |  | ||||||
| 			/*
 |  | ||||||
| 			 * the main goal here is that we don't want to |  | ||||||
| 			 * block if we're going to be able to submit |  | ||||||
| 			 * more requests without blocking. |  | ||||||
| 			 * |  | ||||||
| 			 * This code does two great things, it pokes into |  | ||||||
| 			 * the elevator code from a filesystem _and_ |  | ||||||
| 			 * it makes assumptions about how batching works. |  | ||||||
| 			 */ |  | ||||||
| 			if (ioc && ioc->nr_batch_requests > 0 && |  | ||||||
| 			    time_before(jiffies, ioc->last_waited + HZ/50UL) && |  | ||||||
| 			    (last_waited == 0 || |  | ||||||
| 			     ioc->last_waited == last_waited)) { |  | ||||||
| 				/*
 |  | ||||||
| 				 * we want to go through our batch of |  | ||||||
| 				 * requests and stop.  So, we copy out |  | ||||||
| 				 * the ioc->last_waited time and test |  | ||||||
| 				 * against it before looping |  | ||||||
| 				 */ |  | ||||||
| 				last_waited = ioc->last_waited; |  | ||||||
| 				cond_resched(); |  | ||||||
| 				continue; |  | ||||||
| 			} |  | ||||||
| 			spin_lock(&device->io_lock); |  | ||||||
| 			requeue_list(pending_bios, pending, tail); |  | ||||||
| 			device->running_pending = 1; |  | ||||||
| 
 |  | ||||||
| 			spin_unlock(&device->io_lock); |  | ||||||
| 			btrfs_queue_work(fs_info->submit_workers, |  | ||||||
| 					 &device->work); |  | ||||||
| 			goto done; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	cond_resched(); |  | ||||||
| 	if (again) |  | ||||||
| 		goto loop; |  | ||||||
| 
 |  | ||||||
| 	spin_lock(&device->io_lock); |  | ||||||
| 	if (device->pending_bios.head || device->pending_sync_bios.head) |  | ||||||
| 		goto loop_lock; |  | ||||||
| 	spin_unlock(&device->io_lock); |  | ||||||
| 
 |  | ||||||
| done: |  | ||||||
| 	blk_finish_plug(&plug); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void pending_bios_fn(struct btrfs_work *work) |  | ||||||
| { |  | ||||||
| 	struct btrfs_device *device; |  | ||||||
| 
 |  | ||||||
| 	device = container_of(work, struct btrfs_device, work); |  | ||||||
| 	run_scheduled_bios(device); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static bool device_path_matched(const char *path, struct btrfs_device *device) | static bool device_path_matched(const char *path, struct btrfs_device *device) | ||||||
| { | { | ||||||
| 	int found; | 	int found; | ||||||
|  | @ -6628,8 +6420,6 @@ struct btrfs_device *btrfs_alloc_device(struct btrfs_fs_info *fs_info, | ||||||
| 	else | 	else | ||||||
| 		generate_random_uuid(dev->uuid); | 		generate_random_uuid(dev->uuid); | ||||||
| 
 | 
 | ||||||
| 	btrfs_init_work(&dev->work, pending_bios_fn, NULL, NULL); |  | ||||||
| 
 |  | ||||||
| 	return dev; | 	return dev; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -18,10 +18,6 @@ extern struct mutex uuid_mutex; | ||||||
| #define BTRFS_STRIPE_LEN	SZ_64K | #define BTRFS_STRIPE_LEN	SZ_64K | ||||||
| 
 | 
 | ||||||
| struct buffer_head; | struct buffer_head; | ||||||
| struct btrfs_pending_bios { |  | ||||||
| 	struct bio *head; |  | ||||||
| 	struct bio *tail; |  | ||||||
| }; |  | ||||||
| 
 | 
 | ||||||
| struct btrfs_io_geometry { | struct btrfs_io_geometry { | ||||||
| 	/* remaining bytes before crossing a stripe */ | 	/* remaining bytes before crossing a stripe */ | ||||||
|  | @ -68,13 +64,6 @@ struct btrfs_device { | ||||||
| 
 | 
 | ||||||
| 	u64 generation; | 	u64 generation; | ||||||
| 
 | 
 | ||||||
| 	spinlock_t io_lock ____cacheline_aligned; |  | ||||||
| 	int running_pending; |  | ||||||
| 	/* regular prio bios */ |  | ||||||
| 	struct btrfs_pending_bios pending_bios; |  | ||||||
| 	/* sync bios */ |  | ||||||
| 	struct btrfs_pending_bios pending_sync_bios; |  | ||||||
| 
 |  | ||||||
| 	struct block_device *bdev; | 	struct block_device *bdev; | ||||||
| 
 | 
 | ||||||
| 	/* the mode sent to blkdev_get */ | 	/* the mode sent to blkdev_get */ | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Chris Mason
						Chris Mason