mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	devres: add devm_alloc_percpu()
Introduce managed counterparts for alloc_percpu() and free_percpu(). Add devm_alloc_percpu() and devm_free_percpu() into the managed interfaces list. Signed-off-by: Madalin Bucur <madalin.bucur@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									319b0534b9
								
							
						
					
					
						commit
						ff86aae3b4
					
				
					 3 changed files with 89 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -332,6 +332,10 @@ MEM
 | 
			
		|||
MFD
 | 
			
		||||
 devm_mfd_add_devices()
 | 
			
		||||
 | 
			
		||||
PER-CPU MEM
 | 
			
		||||
  devm_alloc_percpu()
 | 
			
		||||
  devm_free_percpu()
 | 
			
		||||
 | 
			
		||||
PCI
 | 
			
		||||
  pcim_enable_device()	: after success, all PCI ops become managed
 | 
			
		||||
  pcim_pin_device()	: keep PCI device enabled after release
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,6 +10,7 @@
 | 
			
		|||
#include <linux/device.h>
 | 
			
		||||
#include <linux/module.h>
 | 
			
		||||
#include <linux/slab.h>
 | 
			
		||||
#include <linux/percpu.h>
 | 
			
		||||
 | 
			
		||||
#include "base.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -985,3 +986,68 @@ void devm_free_pages(struct device *dev, unsigned long addr)
 | 
			
		|||
			       &devres));
 | 
			
		||||
}
 | 
			
		||||
EXPORT_SYMBOL_GPL(devm_free_pages);
 | 
			
		||||
 | 
			
		||||
static void devm_percpu_release(struct device *dev, void *pdata)
 | 
			
		||||
{
 | 
			
		||||
	void __percpu *p;
 | 
			
		||||
 | 
			
		||||
	p = *(void __percpu **)pdata;
 | 
			
		||||
	free_percpu(p);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int devm_percpu_match(struct device *dev, void *data, void *p)
 | 
			
		||||
{
 | 
			
		||||
	struct devres *devr = container_of(data, struct devres, data);
 | 
			
		||||
 | 
			
		||||
	return *(void **)devr->data == p;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * __devm_alloc_percpu - Resource-managed alloc_percpu
 | 
			
		||||
 * @dev: Device to allocate per-cpu memory for
 | 
			
		||||
 * @size: Size of per-cpu memory to allocate
 | 
			
		||||
 * @align: Alignment of per-cpu memory to allocate
 | 
			
		||||
 *
 | 
			
		||||
 * Managed alloc_percpu. Per-cpu memory allocated with this function is
 | 
			
		||||
 * automatically freed on driver detach.
 | 
			
		||||
 *
 | 
			
		||||
 * RETURNS:
 | 
			
		||||
 * Pointer to allocated memory on success, NULL on failure.
 | 
			
		||||
 */
 | 
			
		||||
void __percpu *__devm_alloc_percpu(struct device *dev, size_t size,
 | 
			
		||||
		size_t align)
 | 
			
		||||
{
 | 
			
		||||
	void *p;
 | 
			
		||||
	void __percpu *pcpu;
 | 
			
		||||
 | 
			
		||||
	pcpu = __alloc_percpu(size, align);
 | 
			
		||||
	if (!pcpu)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	p = devres_alloc(devm_percpu_release, sizeof(void *), GFP_KERNEL);
 | 
			
		||||
	if (!p) {
 | 
			
		||||
		free_percpu(pcpu);
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*(void __percpu **)p = pcpu;
 | 
			
		||||
 | 
			
		||||
	devres_add(dev, p);
 | 
			
		||||
 | 
			
		||||
	return pcpu;
 | 
			
		||||
}
 | 
			
		||||
EXPORT_SYMBOL_GPL(__devm_alloc_percpu);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * devm_free_percpu - Resource-managed free_percpu
 | 
			
		||||
 * @dev: Device this memory belongs to
 | 
			
		||||
 * @pdata: Per-cpu memory to free
 | 
			
		||||
 *
 | 
			
		||||
 * Free memory allocated with devm_alloc_percpu().
 | 
			
		||||
 */
 | 
			
		||||
void devm_free_percpu(struct device *dev, void __percpu *pdata)
 | 
			
		||||
{
 | 
			
		||||
	WARN_ON(devres_destroy(dev, devm_percpu_release, devm_percpu_match,
 | 
			
		||||
			       (void *)pdata));
 | 
			
		||||
}
 | 
			
		||||
EXPORT_SYMBOL_GPL(devm_free_percpu);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -698,6 +698,25 @@ static inline int devm_add_action_or_reset(struct device *dev,
 | 
			
		|||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * devm_alloc_percpu - Resource-managed alloc_percpu
 | 
			
		||||
 * @dev: Device to allocate per-cpu memory for
 | 
			
		||||
 * @type: Type to allocate per-cpu memory for
 | 
			
		||||
 *
 | 
			
		||||
 * Managed alloc_percpu. Per-cpu memory allocated with this function is
 | 
			
		||||
 * automatically freed on driver detach.
 | 
			
		||||
 *
 | 
			
		||||
 * RETURNS:
 | 
			
		||||
 * Pointer to allocated memory on success, NULL on failure.
 | 
			
		||||
 */
 | 
			
		||||
#define devm_alloc_percpu(dev, type)      \
 | 
			
		||||
	((typeof(type) __percpu *)__devm_alloc_percpu((dev), sizeof(type), \
 | 
			
		||||
						      __alignof__(type)))
 | 
			
		||||
 | 
			
		||||
void __percpu *__devm_alloc_percpu(struct device *dev, size_t size,
 | 
			
		||||
				   size_t align);
 | 
			
		||||
void devm_free_percpu(struct device *dev, void __percpu *pdata);
 | 
			
		||||
 | 
			
		||||
struct device_dma_parameters {
 | 
			
		||||
	/*
 | 
			
		||||
	 * a low level driver may set these to teach IOMMU code about
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue