-
Chris Mason authored
Async CRCs and compression submit IO through helper threads, which means they have IO priority inversions when cgroup IO controllers are in use. This flags all of the writes submitted by btrfs helper threads as REQ_CGROUP_PUNT. submit_bio() will punt these to dedicated per-blkcg work items to avoid the priority inversion. For the compression code, we take a reference on the wbc's blkg css and pass it down to the async workers. For the async CRCs, the bio already has the correct css, we just need to tell the block layer to use REQ_CGROUP_PUNT. Reviewed-by:
Josef Bacik <josef@toxicpanda.com> Signed-off-by:
Chris Mason <clm@fb.com> Modified-and-reviewed-by:
Tejun Heo <tj@kernel.org> Signed-off-by:
David Sterba <dsterba@suse.com>
ec39f769
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
extent_io.c 154.71 KiB
// SPDX-License-Identifier: GPL-2.0
#include <linux/bitops.h>
#include <linux/slab.h>
#include <linux/bio.h>
#include <linux/mm.h>
#include <linux/pagemap.h>
#include <linux/page-flags.h>
#include <linux/spinlock.h>
#include <linux/blkdev.h>
#include <linux/swap.h>
#include <linux/writeback.h>
#include <linux/pagevec.h>
#include <linux/prefetch.h>
#include <linux/cleancache.h>
#include "extent_io.h"
#include "extent-io-tree.h"
#include "extent_map.h"
#include "ctree.h"
#include "btrfs_inode.h"
#include "volumes.h"
#include "check-integrity.h"
#include "locking.h"
#include "rcu-string.h"
#include "backref.h"
#include "disk-io.h"
static struct kmem_cache *extent_state_cache;
static struct kmem_cache *extent_buffer_cache;
static struct bio_set btrfs_bioset;
static inline bool extent_state_in_tree(const struct extent_state *state)
{
return !RB_EMPTY_NODE(&state->rb_node);
}
#ifdef CONFIG_BTRFS_DEBUG
static LIST_HEAD(buffers);
static LIST_HEAD(states);
static DEFINE_SPINLOCK(leak_lock);
static inline
void btrfs_leak_debug_add(struct list_head *new, struct list_head *head)
{
unsigned long flags;
spin_lock_irqsave(&leak_lock, flags);
list_add(new, head);
spin_unlock_irqrestore(&leak_lock, flags);
}
static inline
void btrfs_leak_debug_del(struct list_head *entry)
{
unsigned long flags;
spin_lock_irqsave(&leak_lock, flags);
list_del(entry);
spin_unlock_irqrestore(&leak_lock, flags);
}
static inline void btrfs_extent_buffer_leak_debug_check(void)
{
struct extent_buffer *eb;
while (!list_empty(&buffers)) {
eb = list_entry(buffers.next, struct extent_buffer, leak_list);
pr_err("BTRFS: buffer leak start %llu len %lu refs %d bflags %lu\n",
eb->start, eb->len, atomic_read(&eb->refs), eb->bflags);