mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	md: convert to kvmalloc
The code really just wants a big flat buffer, so just do that. Link: http://lkml.kernel.org/r/20181217131929.11727-3-kent.overstreet@gmail.com Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com> Reviewed-by: Matthew Wilcox <willy@infradead.org> Cc: Shaohua Li <shli@kernel.org> Cc: Alexey Dobriyan <adobriyan@gmail.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Dave Hansen <dave.hansen@intel.com> Cc: Eric Paris <eparis@parisplace.org> Cc: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> Cc: Neil Horman <nhorman@tuxdriver.com> Cc: Paul Moore <paul@paul-moore.com> Cc: Pravin B Shelar <pshelar@ovn.org> Cc: Stephen Smalley <sds@tycho.nsa.gov> Cc: Vlad Yasevich <vyasevich@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
		
							parent
							
								
									ee9c5e6755
								
							
						
					
					
						commit
						b330e6a49d
					
				
					 3 changed files with 45 additions and 55 deletions
				
			
		| 
						 | 
					@ -16,7 +16,6 @@
 | 
				
			||||||
#include <linux/blkdev.h>
 | 
					#include <linux/blkdev.h>
 | 
				
			||||||
#include <linux/slab.h>
 | 
					#include <linux/slab.h>
 | 
				
			||||||
#include <linux/crc32c.h>
 | 
					#include <linux/crc32c.h>
 | 
				
			||||||
#include <linux/flex_array.h>
 | 
					 | 
				
			||||||
#include <linux/async_tx.h>
 | 
					#include <linux/async_tx.h>
 | 
				
			||||||
#include <linux/raid/md_p.h>
 | 
					#include <linux/raid/md_p.h>
 | 
				
			||||||
#include "md.h"
 | 
					#include "md.h"
 | 
				
			||||||
| 
						 | 
					@ -165,7 +164,7 @@ ops_run_partial_parity(struct stripe_head *sh, struct raid5_percpu *percpu,
 | 
				
			||||||
		       struct dma_async_tx_descriptor *tx)
 | 
							       struct dma_async_tx_descriptor *tx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int disks = sh->disks;
 | 
						int disks = sh->disks;
 | 
				
			||||||
	struct page **srcs = flex_array_get(percpu->scribble, 0);
 | 
						struct page **srcs = percpu->scribble;
 | 
				
			||||||
	int count = 0, pd_idx = sh->pd_idx, i;
 | 
						int count = 0, pd_idx = sh->pd_idx, i;
 | 
				
			||||||
	struct async_submit_ctl submit;
 | 
						struct async_submit_ctl submit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -196,8 +195,7 @@ ops_run_partial_parity(struct stripe_head *sh, struct raid5_percpu *percpu,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	init_async_submit(&submit, ASYNC_TX_FENCE|ASYNC_TX_XOR_ZERO_DST, tx,
 | 
						init_async_submit(&submit, ASYNC_TX_FENCE|ASYNC_TX_XOR_ZERO_DST, tx,
 | 
				
			||||||
			  NULL, sh, flex_array_get(percpu->scribble, 0)
 | 
								  NULL, sh, (void *) (srcs + sh->disks + 2));
 | 
				
			||||||
			  + sizeof(struct page *) * (sh->disks + 2));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (count == 1)
 | 
						if (count == 1)
 | 
				
			||||||
		tx = async_memcpy(sh->ppl_page, srcs[0], 0, 0, PAGE_SIZE,
 | 
							tx = async_memcpy(sh->ppl_page, srcs[0], 0, 0, PAGE_SIZE,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,7 +54,6 @@
 | 
				
			||||||
#include <linux/slab.h>
 | 
					#include <linux/slab.h>
 | 
				
			||||||
#include <linux/ratelimit.h>
 | 
					#include <linux/ratelimit.h>
 | 
				
			||||||
#include <linux/nodemask.h>
 | 
					#include <linux/nodemask.h>
 | 
				
			||||||
#include <linux/flex_array.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <trace/events/block.h>
 | 
					#include <trace/events/block.h>
 | 
				
			||||||
#include <linux/list_sort.h>
 | 
					#include <linux/list_sort.h>
 | 
				
			||||||
| 
						 | 
					@ -1394,22 +1393,16 @@ static void ops_complete_compute(void *stripe_head_ref)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* return a pointer to the address conversion region of the scribble buffer */
 | 
					/* return a pointer to the address conversion region of the scribble buffer */
 | 
				
			||||||
static addr_conv_t *to_addr_conv(struct stripe_head *sh,
 | 
					static struct page **to_addr_page(struct raid5_percpu *percpu, int i)
 | 
				
			||||||
				 struct raid5_percpu *percpu, int i)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	void *addr;
 | 
						return percpu->scribble + i * percpu->scribble_obj_size;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	addr = flex_array_get(percpu->scribble, i);
 | 
					 | 
				
			||||||
	return addr + sizeof(struct page *) * (sh->disks + 2);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* return a pointer to the address conversion region of the scribble buffer */
 | 
					/* return a pointer to the address conversion region of the scribble buffer */
 | 
				
			||||||
static struct page **to_addr_page(struct raid5_percpu *percpu, int i)
 | 
					static addr_conv_t *to_addr_conv(struct stripe_head *sh,
 | 
				
			||||||
 | 
									 struct raid5_percpu *percpu, int i)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	void *addr;
 | 
						return (void *) (to_addr_page(percpu, i) + sh->disks + 2);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	addr = flex_array_get(percpu->scribble, i);
 | 
					 | 
				
			||||||
	return addr;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct dma_async_tx_descriptor *
 | 
					static struct dma_async_tx_descriptor *
 | 
				
			||||||
| 
						 | 
					@ -2238,21 +2231,23 @@ static int grow_stripes(struct r5conf *conf, int num)
 | 
				
			||||||
 * calculate over all devices (not just the data blocks), using zeros in place
 | 
					 * calculate over all devices (not just the data blocks), using zeros in place
 | 
				
			||||||
 * of the P and Q blocks.
 | 
					 * of the P and Q blocks.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static struct flex_array *scribble_alloc(int num, int cnt, gfp_t flags)
 | 
					static int scribble_alloc(struct raid5_percpu *percpu,
 | 
				
			||||||
 | 
								  int num, int cnt, gfp_t flags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct flex_array *ret;
 | 
						size_t obj_size =
 | 
				
			||||||
	size_t len;
 | 
							sizeof(struct page *) * (num+2) +
 | 
				
			||||||
 | 
							sizeof(addr_conv_t) * (num+2);
 | 
				
			||||||
 | 
						void *scribble;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	len = sizeof(struct page *) * (num+2) + sizeof(addr_conv_t) * (num+2);
 | 
						scribble = kvmalloc_array(cnt, obj_size, flags);
 | 
				
			||||||
	ret = flex_array_alloc(len, cnt, flags);
 | 
						if (!scribble)
 | 
				
			||||||
	if (!ret)
 | 
							return -ENOMEM;
 | 
				
			||||||
		return NULL;
 | 
					
 | 
				
			||||||
	/* always prealloc all elements, so no locking is required */
 | 
						kvfree(percpu->scribble);
 | 
				
			||||||
	if (flex_array_prealloc(ret, 0, cnt, flags)) {
 | 
					
 | 
				
			||||||
		flex_array_free(ret);
 | 
						percpu->scribble = scribble;
 | 
				
			||||||
		return NULL;
 | 
						percpu->scribble_obj_size = obj_size;
 | 
				
			||||||
	}
 | 
						return 0;
 | 
				
			||||||
	return ret;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int resize_chunks(struct r5conf *conf, int new_disks, int new_sectors)
 | 
					static int resize_chunks(struct r5conf *conf, int new_disks, int new_sectors)
 | 
				
			||||||
| 
						 | 
					@ -2270,23 +2265,18 @@ static int resize_chunks(struct r5conf *conf, int new_disks, int new_sectors)
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	mddev_suspend(conf->mddev);
 | 
						mddev_suspend(conf->mddev);
 | 
				
			||||||
	get_online_cpus();
 | 
						get_online_cpus();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for_each_present_cpu(cpu) {
 | 
						for_each_present_cpu(cpu) {
 | 
				
			||||||
		struct raid5_percpu *percpu;
 | 
							struct raid5_percpu *percpu;
 | 
				
			||||||
		struct flex_array *scribble;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		percpu = per_cpu_ptr(conf->percpu, cpu);
 | 
							percpu = per_cpu_ptr(conf->percpu, cpu);
 | 
				
			||||||
		scribble = scribble_alloc(new_disks,
 | 
							err = scribble_alloc(percpu, new_disks,
 | 
				
			||||||
					  new_sectors / STRIPE_SECTORS,
 | 
									     new_sectors / STRIPE_SECTORS,
 | 
				
			||||||
					  GFP_NOIO);
 | 
									     GFP_NOIO);
 | 
				
			||||||
 | 
							if (err)
 | 
				
			||||||
		if (scribble) {
 | 
					 | 
				
			||||||
			flex_array_free(percpu->scribble);
 | 
					 | 
				
			||||||
			percpu->scribble = scribble;
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			err = -ENOMEM;
 | 
					 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	put_online_cpus();
 | 
						put_online_cpus();
 | 
				
			||||||
	mddev_resume(conf->mddev);
 | 
						mddev_resume(conf->mddev);
 | 
				
			||||||
	if (!err) {
 | 
						if (!err) {
 | 
				
			||||||
| 
						 | 
					@ -6742,25 +6732,26 @@ raid5_size(struct mddev *mddev, sector_t sectors, int raid_disks)
 | 
				
			||||||
static void free_scratch_buffer(struct r5conf *conf, struct raid5_percpu *percpu)
 | 
					static void free_scratch_buffer(struct r5conf *conf, struct raid5_percpu *percpu)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	safe_put_page(percpu->spare_page);
 | 
						safe_put_page(percpu->spare_page);
 | 
				
			||||||
	if (percpu->scribble)
 | 
					 | 
				
			||||||
		flex_array_free(percpu->scribble);
 | 
					 | 
				
			||||||
	percpu->spare_page = NULL;
 | 
						percpu->spare_page = NULL;
 | 
				
			||||||
 | 
						kvfree(percpu->scribble);
 | 
				
			||||||
	percpu->scribble = NULL;
 | 
						percpu->scribble = NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int alloc_scratch_buffer(struct r5conf *conf, struct raid5_percpu *percpu)
 | 
					static int alloc_scratch_buffer(struct r5conf *conf, struct raid5_percpu *percpu)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (conf->level == 6 && !percpu->spare_page)
 | 
						if (conf->level == 6 && !percpu->spare_page) {
 | 
				
			||||||
		percpu->spare_page = alloc_page(GFP_KERNEL);
 | 
							percpu->spare_page = alloc_page(GFP_KERNEL);
 | 
				
			||||||
	if (!percpu->scribble)
 | 
							if (!percpu->spare_page)
 | 
				
			||||||
		percpu->scribble = scribble_alloc(max(conf->raid_disks,
 | 
								return -ENOMEM;
 | 
				
			||||||
						      conf->previous_raid_disks),
 | 
						}
 | 
				
			||||||
						  max(conf->chunk_sectors,
 | 
					 | 
				
			||||||
						      conf->prev_chunk_sectors)
 | 
					 | 
				
			||||||
						   / STRIPE_SECTORS,
 | 
					 | 
				
			||||||
						  GFP_KERNEL);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!percpu->scribble || (conf->level == 6 && !percpu->spare_page)) {
 | 
						if (scribble_alloc(percpu,
 | 
				
			||||||
 | 
								   max(conf->raid_disks,
 | 
				
			||||||
 | 
								       conf->previous_raid_disks),
 | 
				
			||||||
 | 
								   max(conf->chunk_sectors,
 | 
				
			||||||
 | 
								       conf->prev_chunk_sectors)
 | 
				
			||||||
 | 
								   / STRIPE_SECTORS,
 | 
				
			||||||
 | 
								   GFP_KERNEL)) {
 | 
				
			||||||
		free_scratch_buffer(conf, percpu);
 | 
							free_scratch_buffer(conf, percpu);
 | 
				
			||||||
		return -ENOMEM;
 | 
							return -ENOMEM;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -638,10 +638,11 @@ struct r5conf {
 | 
				
			||||||
	/* per cpu variables */
 | 
						/* per cpu variables */
 | 
				
			||||||
	struct raid5_percpu {
 | 
						struct raid5_percpu {
 | 
				
			||||||
		struct page	*spare_page; /* Used when checking P/Q in raid6 */
 | 
							struct page	*spare_page; /* Used when checking P/Q in raid6 */
 | 
				
			||||||
		struct flex_array *scribble;   /* space for constructing buffer
 | 
							void		*scribble;  /* space for constructing buffer
 | 
				
			||||||
					      * lists and performing address
 | 
										     * lists and performing address
 | 
				
			||||||
					      * conversions
 | 
										     * conversions
 | 
				
			||||||
					      */
 | 
										     */
 | 
				
			||||||
 | 
							int scribble_obj_size;
 | 
				
			||||||
	} __percpu *percpu;
 | 
						} __percpu *percpu;
 | 
				
			||||||
	int scribble_disks;
 | 
						int scribble_disks;
 | 
				
			||||||
	int scribble_sectors;
 | 
						int scribble_sectors;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue