Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Removing ZERO_PAGE abd_alloc_zero_scatter #10428

Merged
merged 1 commit into from
Jun 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion include/sys/abd.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ typedef int abd_iter_func_t(void *buf, size_t len, void *priv);
typedef int abd_iter_func2_t(void *bufa, void *bufb, size_t len, void *priv);

extern int zfs_abd_scatter_enabled;
extern abd_t *abd_zero_scatter;

/*
* Allocations and deallocations
Expand Down
2 changes: 2 additions & 0 deletions include/sys/abd_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ struct abd_iter {
struct scatterlist *iter_sg; /* current sg */
};

extern abd_t *abd_zero_scatter;

abd_t *abd_gang_get_offset(abd_t *, size_t *);

/*
Expand Down
33 changes: 21 additions & 12 deletions module/os/linux/zfs/abd_os.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,13 @@ int zfs_abd_scatter_min_size = 512 * 3;
*/
abd_t *abd_zero_scatter = NULL;

struct page;
/*
* abd_zero_page we will be an allocated zero'd PAGESIZE buffer, which is
* assigned to set each of the pages of abd_zero_scatter.
*/
static struct page *abd_zero_page = NULL;

static kmem_cache_t *abd_cache = NULL;
static kstat_t *abd_ksp;

Expand Down Expand Up @@ -439,18 +446,24 @@ abd_free_chunks(abd_t *abd)

/*
* Allocate scatter ABD of size SPA_MAXBLOCKSIZE, where each page in
* the scatterlist will be set to ZERO_PAGE(0). ZERO_PAGE(0) returns
* a global shared page that is always zero'd out.
* the scatterlist will be set to the zero'd out buffer abd_zero_page.
*/
static void
abd_alloc_zero_scatter(void)
{
struct scatterlist *sg = NULL;
struct sg_table table;
gfp_t gfp = __GFP_NOWARN | GFP_NOIO;
gfp_t gfp_zero_page = gfp | __GFP_ZERO;
int nr_pages = abd_chunkcnt_for_bytes(SPA_MAXBLOCKSIZE);
int i = 0;

while ((abd_zero_page = __page_cache_alloc(gfp_zero_page)) == NULL) {
ABDSTAT_BUMP(abdstat_scatter_page_alloc_retry);
schedule_timeout_interruptible(1);
}
abd_mark_zfs_page(abd_zero_page);

while (sg_alloc_table(&table, nr_pages, gfp)) {
ABDSTAT_BUMP(abdstat_scatter_sg_table_retry);
schedule_timeout_interruptible(1);
Expand All @@ -468,7 +481,7 @@ abd_alloc_zero_scatter(void)
zfs_refcount_create(&abd_zero_scatter->abd_children);

abd_for_each_sg(abd_zero_scatter, sg, nr_pages, i) {
sg_set_page(sg, ZERO_PAGE(0), PAGESIZE, 0);
sg_set_page(sg, abd_zero_page, PAGESIZE, 0);
}

ABDSTAT_BUMP(abdstat_scatter_cnt);
Expand All @@ -478,14 +491,6 @@ abd_alloc_zero_scatter(void)

#else /* _KERNEL */

struct page;

/*
* In user space abd_zero_page we will be an allocated zero'd PAGESIZE
* buffer, which is assigned to set each of the pages of abd_zero_scatter.
*/
static struct page *abd_zero_page = NULL;

#ifndef PAGE_SHIFT
#define PAGE_SHIFT (highbit64(PAGESIZE)-1)
#endif
Expand Down Expand Up @@ -680,7 +685,11 @@ abd_free_zero_scatter(void)
abd_free_sg_table(abd_zero_scatter);
abd_free_struct(abd_zero_scatter);
abd_zero_scatter = NULL;
#if !defined(_KERNEL)
ASSERT3P(abd_zero_page, !=, NULL);
#if defined(_KERNEL)
abd_unmark_zfs_page(abd_zero_page);
__free_page(abd_zero_page);
#else
umem_free(abd_zero_page, PAGESIZE);
#endif /* _KERNEL */
}
Expand Down