fs/btrfs/async-thread.c

Source file repositories/reference/linux-study-clean/fs/btrfs/async-thread.c

File Facts

System
Linux kernel
Corpus path
fs/btrfs/async-thread.c
Extension
.c
Size
9954 bytes
Lines
373
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

struct btrfs_workqueue {
	struct workqueue_struct *normal_wq;

	/* File system this workqueue services */
	struct btrfs_fs_info *fs_info;

	/* List head pointing to ordered work list */
	struct list_head ordered_list;

	/* Spinlock for ordered_list */
	spinlock_t list_lock;

	/* Thresholding related variants */
	atomic_t pending;

	/* Up limit of concurrency workers */
	int limit_active;

	/* Current number of concurrency workers */
	int current_active;

	/* Threshold to change current_active */
	int thresh;
	unsigned int count;
	spinlock_t thres_lock;
};

struct btrfs_fs_info * __pure btrfs_workqueue_owner(const struct btrfs_workqueue *wq)
{
	return wq->fs_info;
}

struct btrfs_fs_info * __pure btrfs_work_owner(const struct btrfs_work *work)
{
	return work->wq->fs_info;
}

bool btrfs_workqueue_normal_congested(const struct btrfs_workqueue *wq)
{
	/*
	 * We could compare wq->pending with num_online_cpus()
	 * to support "thresh == NO_THRESHOLD" case, but it requires
	 * moving up atomic_inc/dec in thresh_queue/exec_hook. Let's
	 * postpone it until someone needs the support of that case.
	 */
	if (wq->thresh == NO_THRESHOLD)
		return false;

	return atomic_read(&wq->pending) > wq->thresh * 2;
}

static void btrfs_init_workqueue(struct btrfs_workqueue *wq,
				 struct btrfs_fs_info *fs_info)
{
	wq->fs_info = fs_info;
	atomic_set(&wq->pending, 0);
	INIT_LIST_HEAD(&wq->ordered_list);
	spin_lock_init(&wq->list_lock);
	spin_lock_init(&wq->thres_lock);
}

struct btrfs_workqueue *btrfs_alloc_workqueue(struct btrfs_fs_info *fs_info,
					      const char *name, unsigned int flags,
					      int limit_active, int thresh)
{
	struct btrfs_workqueue *ret = kzalloc_obj(*ret);

	if (!ret)
		return NULL;

	btrfs_init_workqueue(ret, fs_info);

	ret->limit_active = limit_active;
	if (thresh == 0)
		thresh = DEFAULT_THRESHOLD;
	/* For low threshold, disabling threshold is a better choice */
	if (thresh < DEFAULT_THRESHOLD) {
		ret->current_active = limit_active;
		ret->thresh = NO_THRESHOLD;
	} else {
		/*
		 * For threshold-able wq, let its concurrency grow on demand.
		 * Use minimal max_active at alloc time to reduce resource
		 * usage.
		 */
		ret->current_active = 1;
		ret->thresh = thresh;
	}

	ret->normal_wq = alloc_workqueue("btrfs-%s", flags, ret->current_active,

Annotation

Implementation Notes