2018-06-06 05:42:14 +03:00
// SPDX-License-Identifier: GPL-2.0
2005-04-17 02:20:36 +04:00
/*
2005-11-02 06:58:39 +03:00
* Copyright ( c ) 2000 - 2005 Silicon Graphics , Inc .
* All Rights Reserved .
2005-04-17 02:20:36 +04:00
*/
2017-02-02 22:43:54 +03:00
# include <linux/sched/mm.h>
2006-10-20 10:28:16 +04:00
# include <linux/backing-dev.h>
2005-04-17 02:20:36 +04:00
# include "kmem.h"
2011-03-07 02:00:35 +03:00
# include "xfs_message.h"
2005-04-17 02:20:36 +04:00
void *
2012-04-02 14:24:04 +04:00
kmem_alloc ( size_t size , xfs_km_flags_t flags )
2005-04-17 02:20:36 +04:00
{
2005-10-21 11:20:48 +04:00
int retries = 0 ;
gfp_t lflags = kmem_flags_convert ( flags ) ;
void * ptr ;
2005-04-17 02:20:36 +04:00
do {
2010-01-21 00:55:30 +03:00
ptr = kmalloc ( size , lflags ) ;
2005-04-17 02:20:36 +04:00
if ( ptr | | ( flags & ( KM_MAYFAIL | KM_NOSLEEP ) ) )
return ptr ;
if ( ! ( + + retries % 100 ) )
2011-03-07 02:00:35 +03:00
xfs_err ( NULL ,
2015-10-12 08:04:45 +03:00
" %s(%u) possible memory allocation deadlock size %u in %s (mode:0x%x) " ,
2015-10-12 07:41:29 +03:00
current - > comm , current - > pid ,
2015-10-12 08:04:45 +03:00
( unsigned int ) size , __func__ , lflags ) ;
2009-07-09 16:52:32 +04:00
congestion_wait ( BLK_RW_ASYNC , HZ / 50 ) ;
2005-04-17 02:20:36 +04:00
} while ( 1 ) ;
}
2013-09-02 14:53:00 +04:00
void *
2018-03-07 04:03:28 +03:00
kmem_alloc_large ( size_t size , xfs_km_flags_t flags )
2013-09-02 14:53:00 +04:00
{
2017-05-04 00:53:19 +03:00
unsigned nofs_flag = 0 ;
2013-09-02 14:53:00 +04:00
void * ptr ;
2014-03-07 09:19:14 +04:00
gfp_t lflags ;
2013-09-02 14:53:00 +04:00
2018-03-07 04:03:28 +03:00
ptr = kmem_alloc ( size , flags | KM_MAYFAIL ) ;
2013-09-02 14:53:00 +04:00
if ( ptr )
return ptr ;
2014-03-07 09:19:14 +04:00
/*
* __vmalloc ( ) will allocate data pages and auxillary structures ( e . g .
* pagetables ) with GFP_KERNEL , yet we may be under GFP_NOFS context
* here . Hence we need to tell memory reclaim that we are in such a
2017-05-04 00:53:19 +03:00
* context via PF_MEMALLOC_NOFS to prevent memory reclaim re - entering
2014-03-07 09:19:14 +04:00
* the filesystem here and potentially deadlocking .
*/
2017-05-04 00:53:19 +03:00
if ( flags & KM_NOFS )
nofs_flag = memalloc_nofs_save ( ) ;
2014-03-07 09:19:14 +04:00
lflags = kmem_flags_convert ( flags ) ;
2018-03-07 04:03:28 +03:00
ptr = __vmalloc ( size , lflags , PAGE_KERNEL ) ;
2014-03-07 09:19:14 +04:00
2017-05-04 00:53:19 +03:00
if ( flags & KM_NOFS )
memalloc_nofs_restore ( nofs_flag ) ;
2014-03-07 09:19:14 +04:00
return ptr ;
2013-09-02 14:53:00 +04:00
}
2005-04-17 02:20:36 +04:00
void *
2016-04-06 02:47:01 +03:00
kmem_realloc ( const void * old , size_t newsize , xfs_km_flags_t flags )
2005-04-17 02:20:36 +04:00
{
2016-04-06 02:47:01 +03:00
int retries = 0 ;
gfp_t lflags = kmem_flags_convert ( flags ) ;
void * ptr ;
2005-04-17 02:20:36 +04:00
2016-04-06 02:47:01 +03:00
do {
ptr = krealloc ( old , newsize , lflags ) ;
if ( ptr | | ( flags & ( KM_MAYFAIL | KM_NOSLEEP ) ) )
return ptr ;
if ( ! ( + + retries % 100 ) )
xfs_err ( NULL ,
" %s(%u) possible memory allocation deadlock size %zu in %s (mode:0x%x) " ,
current - > comm , current - > pid ,
newsize , __func__ , lflags ) ;
congestion_wait ( BLK_RW_ASYNC , HZ / 50 ) ;
} while ( 1 ) ;
2005-04-17 02:20:36 +04:00
}
void *
2012-04-02 14:24:04 +04:00
kmem_zone_alloc ( kmem_zone_t * zone , xfs_km_flags_t flags )
2005-04-17 02:20:36 +04:00
{
2005-10-21 11:20:48 +04:00
int retries = 0 ;
gfp_t lflags = kmem_flags_convert ( flags ) ;
void * ptr ;
2005-04-17 02:20:36 +04:00
do {
ptr = kmem_cache_alloc ( zone , lflags ) ;
if ( ptr | | ( flags & ( KM_MAYFAIL | KM_NOSLEEP ) ) )
return ptr ;
if ( ! ( + + retries % 100 ) )
2011-03-07 02:00:35 +03:00
xfs_err ( NULL ,
2015-10-12 07:41:29 +03:00
" %s(%u) possible memory allocation deadlock in %s (mode:0x%x) " ,
current - > comm , current - > pid ,
__func__ , lflags ) ;
2009-07-09 16:52:32 +04:00
congestion_wait ( BLK_RW_ASYNC , HZ / 50 ) ;
2005-04-17 02:20:36 +04:00
} while ( 1 ) ;
}