linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* exofs/ore: allocation of _ore_get_io_state()
@ 2012-04-16 14:53 Idan Kedar
  2012-05-23 21:00 ` Boaz Harrosh
  0 siblings, 1 reply; 4+ messages in thread
From: Idan Kedar @ 2012-04-16 14:53 UTC (permalink / raw)
  To: Linux FS Maling List

_ore_get_io_state is supposed to allocate a struct ore_io_state, which is
variable length. Setting aside the uglification argument which gave birth
to the patch "pnfs-obj: Uglify objio_segment allocation for the sake of
the principle :-(", the above function checks if the memory it needs to
allocate is bigger than a page, and if so, separates it into two
allocations. why is this done?

from include/linux/slab.h:
>/*
> * The largest kmalloc size supported by the slab allocators is
> * 32 megabyte (2^25) or the maximum allocatable page order if that is
> * less than 32 MB.
> *
> * WARNING: Its not easy to increase this value since the allocators have
> * to do various tricks to work around compiler limitations in order to
> * ensure proper constant folding.
> */
>#define KMALLOC_SHIFT_HIGH      ((MAX_ORDER + PAGE_SHIFT - 1) <= 25 ? \
>                                (MAX_ORDER + PAGE_SHIFT - 1) : 25)
>
>#define KMALLOC_MAX_SIZE        (1UL << KMALLOC_SHIFT_HIGH)
>#define KMALLOC_MAX_ORDER       (KMALLOC_SHIFT_HIGH - PAGE_SHIFT)

If kmalloc can allocate 32MB, why check one page, like so?

from fs/exofs/ore.c:
>struct __alloc_all_io_state {
>	struct ore_io_state ios;
>	struct ore_per_dev_state per_dev[numdevs];
>	union {
>		struct osd_sg_entry sglist[sgs_per_dev * numdevs];
>		struct page *pages[num_par_pages];
>	};
>} *_aios;
>
>if (likely(sizeof(*_aios) <= PAGE_SIZE)) {
>	_aios = kzalloc(sizeof(*_aios), GFP_KERNEL);
>	if (unlikely(!_aios)) {
>		EXOFS_DBGMSG("Failed kzalloc bytes=%zd\n",
>			   sizeof(*_aios));
>		*pios = NULL;
>		return -ENOMEM;
>	}
>	pages = num_par_pages ? _aios->pages : NULL;
>	sgilist = sgs_per_dev ? _aios->sglist : NULL;
>	ios = &_aios->ios;
>} else {
>	struct __alloc_small_io_state {
>		struct ore_io_state ios;
>		struct ore_per_dev_state per_dev[numdevs];
>	} *_aio_small;
>	union __extra_part {
>		struct osd_sg_entry sglist[sgs_per_dev * numdevs];
>		struct page *pages[num_par_pages];
>	} *extra_part;
>		_aio_small = kzalloc(sizeof(*_aio_small), GFP_KERNEL);
>	if (unlikely(!_aio_small)) {
>		EXOFS_DBGMSG("Failed alloc first part bytes=%zd\n",
>			   sizeof(*_aio_small));
>		*pios = NULL;
>		return -ENOMEM;
>	}
>	extra_part = kzalloc(sizeof(*extra_part), GFP_KERNEL);
>	if (unlikely(!extra_part)) {
>		EXOFS_DBGMSG("Failed alloc second part bytes=%zd\n",
>			   sizeof(*extra_part));
>		kfree(_aio_small);
>		*pios = NULL;
>		return -ENOMEM;
>	}
>		pages = num_par_pages ? extra_part->pages : NULL;
>	sgilist = sgs_per_dev ? extra_part->sglist : NULL;
>	/* In this case the per_dev[0].sgilist holds the pointer to
>	 * be freed
>	 */
>	ios = &_aio_small->ios;
>	ios->extra_part_alloc = true;
>}

Is there any point to check if the memory is greater than 32MB?


-- 
Idan Kedar
Tonian

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2012-05-24 14:05 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-04-16 14:53 exofs/ore: allocation of _ore_get_io_state() Idan Kedar
2012-05-23 21:00 ` Boaz Harrosh
2012-05-24 11:23   ` Idan Kedar
2012-05-24 14:05     ` Boaz Harrosh

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).