Re: iio, syfs, devres: devm_kmalloc not aligned to pow2 size argument

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 2024/11/14 19:29, Matteo Martelli wrote:
>>>> The address of a chunk allocated with `kmalloc` is aligned to at least
>>>> ARCH_KMALLOC_MINALIGN bytes. For sizes of power of two bytes, the
>>>> alignment is also guaranteed to be at least to the respective size.
>>>>
>>>> To do so I was thinking to try to move the devres metadata after the
>>>> data buffer, so that the latter would directly correspond to pointer
>>>> returned by kmalloc. I then found out that it had been already suggested
>>>> previously to address a memory optimization [2]. Thus I am reporting the
>>>> issue before submitting any patch as some discussions might be helpful
>>>> first.
>>>>
>> no, IMO, that is not good idea absolutely.
> It’s now quite clear to me that the issue is a rare corner case, and the
> potential impact of making such a change does not justify it. However,
> for completeness and future reference, are there any additional reasons
> why this change is a bad idea?

1)
as i ever commented, below existing APIs is very suitable for your
requirements. right ?
addr = devm_get_free_pages(dev, GFP_KERNEL|__GFP_ZERO, 0);
devm_free_pages(dev,addr);

2)
touching existing API which have been used frequently means high risk?

3) if you put the important metadata at the end of the memory block.
   3.1) it is easy to be destroyed by out of memory access.
   3.2) the API will be used to allocate memory with various sizes
        how to seek the tail metadata ?  is it easy to seek it?
   3.3) if you allocate one page, the size to allocate is page size
        + meta size, it will waste memory align.

4) below simple alternative is better than your idea. it keep all
attributes of original kmalloc(). right ?

static int devres_raw_kmalloc_match(struct device *dev, void *res, void *p)
{
	void **ptr = res;
	return *ptr == p;
}

static void devres_raw_kmalloc_release(struct device *dev, void *res)
{
	void **ptr = res;
	kfree(*ptr);
}

void *devm_raw_kmalloc(struct device *dev, size_t size, gfp_t gfp)
{
	void **ptr;
	
	ptr = devres_alloc(devres_raw_kmalloc_release, sizeof(*ptr), GFP_KERNEL);
	f (!ptr)
		return NULL;
	
	*ptr = kmalloc(size, gfp);
	if (!*ptr) {
		devres_free(ptr);
		return NULL;
	}
	devres_add(dev, ptr);
	return *ptr;
}
EXPORT(...)

void *devm_raw_kfree(struct device *dev, void *p)
{
	devres_release(dev, devres_raw_kmalloc_release,
devres_raw_kmalloc_match, p);
}
EXPORT(...)




[Index of Archives]     [Linux RAID]     [Linux SCSI]     [Linux ATA RAID]     [IDE]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Device Mapper]

  Powered by Linux