Messages in this thread |  | | Subject | Re: [PATCH 4/6] lib/scatterlist: Do not leak pages when high-order allocation fails | From | Bart Van Assche <> | Date | Wed, 03 Oct 2018 08:31:40 -0700 |
| |
On Wed, 2018-09-26 at 15:16 +0100, Tvrtko Ursulin wrote: > From: Tvrtko Ursulin <tvrtko.ursulin@intel.com> > > If a higher-order allocation fails, the existing abort and cleanup path > would consider all segments allocated so far as 0-order page allocations > and would therefore leak memory. > > Fix this by cleaning up using sgl_free_n_order which allows the correct > page order to be passed in. > > Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> > Cc: Bart Van Assche <bart.vanassche@wdc.com> > Cc: Hannes Reinecke <hare@suse.com> > Cc: Johannes Thumshirn <jthumshirn@suse.de> > Cc: Jens Axboe <axboe@kernel.dk> > --- > lib/scatterlist.c | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/lib/scatterlist.c b/lib/scatterlist.c > index 3cc01cd82242..0caed79d7291 100644 > --- a/lib/scatterlist.c > +++ b/lib/scatterlist.c > @@ -481,7 +481,7 @@ struct scatterlist *sgl_alloc_order(unsigned long length, unsigned int order, > { > struct scatterlist *sgl, *sg; > struct page *page; > - unsigned int nent, nalloc; > + unsigned int nent, nalloc, i; > u32 elem_len; > > nent = round_up(length, PAGE_SIZE << order) >> (PAGE_SHIFT + order); > @@ -501,17 +501,19 @@ struct scatterlist *sgl_alloc_order(unsigned long length, unsigned int order, > > sg_init_table(sgl, nalloc); > sg = sgl; > + i = 0; > while (length) { > elem_len = min_t(u64, length, PAGE_SIZE << order); > page = alloc_pages(gfp, order); > if (!page) { > - sgl_free(sgl); > + sgl_free_n_order(sgl, i, order); > return NULL; > } > > sg_set_page(sg, page, elem_len, 0); > length -= elem_len; > sg = sg_next(sg); > + i++; > } > WARN_ONCE(length, "length = %ld\n", length); > if (nent_p)
sg_init_table() clears all page pointers and sgl_free_n_order() can handle elements of which the page pointer is zero. So I think if sgl_free_n_order(sgl, i, order) would be changed into sgl_free_n_order(sgl, UINT_MAX, order) that the variable 'i' can be left out.
Bart.
|  |