f2fs: avoid using __GFP_NOFAIL
Subsystems (2)
Chao Yu
maintainerPATCH 1/3 f2fs: avoid using __GFP_NOFAIL
From: Chao Yu <[email protected]>
We will keep __add_ino_entry success all the time, for ENOMEM failure case, we have already handled it with an opened loop code, so we don't have to use redundant __GFP_NOFAIL in radix_tree_preload, remove it.
--- fs/f2fs/checkpoint.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
fs/f2fs/checkpoint.c +7 -3
@@ -405,10 +405,11 @@ static void __add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, {struct inode_management *im = &sbi->im[type];struct ino_entry *e, *tmp; +bool preloaded; tmp =f2fs_kmem_cache_alloc (ino_entry_slab,GFP_NOFS ); retry: -radix_tree_preload (GFP_NOFS | __GFP_NOFAIL); + preloaded = !radix_tree_preload (GFP_NOFS );spin_lock (&im->ino_lock); e =radix_tree_lookup (&im->ino_root, ino);
@@ -416,7 +417,8 @@ static void __add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, e = tmp;if (radix_tree_insert (&im->ino_root, ino, e)) {spin_unlock (&im->ino_lock); -radix_tree_preload_end (); +if (preloaded) +radix_tree_preload_end (); goto retry; }memset (e,0 ,sizeof (struct ino_entry ));
@@ -431,7 +433,9 @@ static void __add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino,f2fs_set_bit (devidx, (char *)&e->dirty_device);spin_unlock (&im->ino_lock); -radix_tree_preload_end (); + +if (preloaded) +radix_tree_preload_end ();if (e != tmp)kmem_cache_free (ino_entry_slab, tmp);
Signature · 1 line
2.14.1.145.gb3622a4ee
Chao Yu
maintainerPATCH 2/3 f2fs: trace checkpoint reason in fsync()
From: Chao Yu <[email protected]>
This patch slightly changes need_do_checkpoint to return the detail info that indicates why we need do checkpoint, then caller could print it with trace message.
--- fs/f2fs/file.c | 34 ++++++++++++++++++---------------- include/trace/events/f2fs.h | 12 ++++++------ 2 files changed, 24 insertions(+), 22 deletions(-)
fs/f2fs/file.c +18 -16
@@ -141,27 +141,29 @@ static int get_parent_ino(struct inode *inode, nid_t *pino)return 1 ; } -static inline bool need_do_checkpoint (struct inode *inode) +static inline int need_do_checkpoint (struct inode *inode) {struct f2fs_sb_info *sbi =F2FS_I_SB (inode); -bool need_cp = false; +int cp_reason =0 ; -if (!S_ISREG (inode->i_mode) || inode->i_nlink !=1 ) - need_cp = true; +if (!S_ISREG (inode->i_mode)) + cp_reason =1 ; +else if (inode->i_nlink !=1 ) + cp_reason =2 ;else if (is_sbi_flag_set (sbi,SBI_NEED_CP )) - need_cp = true; + cp_reason =3 ;else if (file_wrong_pino (inode)) - need_cp = true; + cp_reason =4 ;else if (!space_for_roll_forward (sbi)) - need_cp = true; + cp_reason =5 ;else if (!is_checkpointed_node (sbi,F2FS_I (inode)->i_pino)) - need_cp = true; + cp_reason =6 ;else if (test_opt (sbi,FASTBOOT )) - need_cp = true; + cp_reason =7 ;else if (sbi->active_logs ==2 ) - need_cp = true; + cp_reason =8 ; -return need_cp; +return cp_reason; }static bool need_inode_page_update (struct f2fs_sb_info *sbi,nid_t ino)
@@ -196,7 +198,7 @@ static int f2fs_do_sync_file(struct file *file, loff_t start, loff_t end,struct f2fs_sb_info *sbi =F2FS_I_SB (inode);nid_t ino = inode->i_ino;int ret =0 ; -bool need_cp = false; +bool cp_reason =0 ;struct writeback_control wbc = { .sync_mode =WB_SYNC_ALL , .nr_to_write =LONG_MAX ,
@@ -215,7 +217,7 @@ static int f2fs_do_sync_file(struct file *file, loff_t start, loff_t end,clear_inode_flag (inode,FI_NEED_IPU );if (ret) { -trace_f2fs_sync_file_exit (inode, need_cp, datasync, ret); +trace_f2fs_sync_file_exit (inode, cp_reason, datasync, ret);return ret; }
@@ -246,10 +248,10 @@ static int f2fs_do_sync_file(struct file *file, loff_t start, loff_t end,* sudden-power-off. */ down_read (&F2FS_I (inode)->i_sem); - need_cp =need_do_checkpoint (inode); + cp_reason =need_do_checkpoint (inode);up_read (&F2FS_I (inode)->i_sem); -if (need_cp) { +if (cp_reason) {/* all the dirty node pages should be flushed for POR */ ret =f2fs_sync_fs (inode->i_sb,1 );
@@ -306,7 +308,7 @@ static int f2fs_do_sync_file(struct file *file, loff_t start, loff_t end, }f2fs_update_time (sbi,REQ_TIME ); out: -trace_f2fs_sync_file_exit (inode, need_cp, datasync, ret); +trace_f2fs_sync_file_exit (inode, cp_reason, datasync, ret);f2fs_trace_ios (NULL ,1 );return ret; }
include/trace/events/f2fs.h +6 -6
@@ -210,14 +210,14 @@ DEFINE_EVENT(f2fs__inode, f2fs_sync_file_enter, TRACE_EVENT(f2fs_sync_file_exit, - TP_PROTO(struct inode *inode, int need_cp, int datasync, int ret), + TP_PROTO(struct inode *inode, int cp_reason, int datasync, int ret), - TP_ARGS(inode, need_cp, datasync, ret), + TP_ARGS(inode, cp_reason, datasync, ret), TP_STRUCT__entry( __field(dev_t, dev) __field(ino_t, ino) - __field(int, need_cp) + __field(int, cp_reason) __field(int, datasync) __field(int, ret) ),
@@ -225,15 +225,15 @@ TRACE_EVENT(f2fs_sync_file_exit,TP_fast_assign ( __entry->dev = inode->i_sb->s_dev; __entry->ino = inode->i_ino; - __entry->need_cp = need_cp; + __entry->cp_reason = cp_reason; __entry->datasync = datasync; __entry->ret = ret; ), -TP_printk ("dev = (%d,%d), ino = %lu, checkpoint is %s, " +TP_printk ("dev = (%d,%d), ino = %lu, cp_reason:%d, " "datasync = %d, ret = %d" ,show_dev_ino (__entry), - __entry->need_cp ?"needed" :"not needed" , + __entry->cp_reason, __entry->datasync, __entry->ret) );
Signature · 1 line
2.14.1.145.gb3622a4ee
Jaegeuk Kim
maintainerRe: [PATCH 2/3] f2fs: trace checkpoint reason in fsync()
Quoted 41 lines · Chao Yu
From: Chao Yu <[email protected]>
This patch slightly changes
need_do_checkpointto return the detail info that indicates why we need do checkpoint, then caller could print it with trace message.Signed-off-by Chao Yu <[email protected]>--- fs/f2fs/file.c | 34 ++++++++++++++++++---------------- include/trace/events/f2fs.h | 12 ++++++------ 2 files changed, 24 insertions(+), 22 deletions(-)fs/f2fs/file.c +8
-7@@ -141,27 +141,29 @@ static int get_parent_ino(struct inode *inode, nid_t *pino)return 1 ; } -static inline bool need_do_checkpoint (struct inode *inode) +static inline int need_do_checkpoint (struct inode *inode) {struct f2fs_sb_info *sbi =F2FS_I_SB (inode); -bool need_cp = false; +int cp_reason =0 ; -if (!S_ISREG (inode->i_mode) || inode->i_nlink !=1 ) - need_cp = true; +if (!S_ISREG (inode->i_mode)) + cp_reason =1 ; +else if (inode->i_nlink !=1 ) + cp_reason =2 ;else if (is_sbi_flag_set (sbi,SBI_NEED_CP )) - need_cp = true; + cp_reason =3 ;else if (file_wrong_pino (inode)) - need_cp = true; + cp_reason =4 ;else if (!space_for_roll_forward (sbi)) - need_cp = true;
fs/f2fs/file.c static int get_parent_ino(struct inode *inode, nid_t *pino) · line 164
Quoted 10 lines
fs/f2fs/file.c +4
-3+ cp_reason =5 ; else if (!is_checkpointed_node(sbi, F2FS_I(inode)->i_pino)) - need_cp = true; + cp_reason =6 ; else if (test_opt(sbi, FASTBOOT)) - need_cp = true; + cp_reason =7 ; else if (sbi->active_logs == 2) - need_cp = true; + cp_reason =8 ;
We need to make the numbers by enum so that we could interpret them in tracepoint below.
Thanks,
Quoted 89 lines
fs/f2fs/file.c +6
-6-return need_cp; +return cp_reason; }static bool need_inode_page_update (struct f2fs_sb_info *sbi,nid_t ino)@@ -196,7 +198,7 @@ static int f2fs_do_sync_file(struct file *file, loff_t start, loff_t end,struct f2fs_sb_info *sbi =F2FS_I_SB (inode);nid_t ino = inode->i_ino;int ret =0 ; -bool need_cp = false; +bool cp_reason =0 ;struct writeback_control wbc = { .sync_mode =WB_SYNC_ALL , .nr_to_write =LONG_MAX ,@@ -215,7 +217,7 @@ static int f2fs_do_sync_file(struct file *file, loff_t start, loff_t end,clear_inode_flag (inode,FI_NEED_IPU );if (ret) { -trace_f2fs_sync_file_exit (inode, need_cp, datasync, ret); +trace_f2fs_sync_file_exit (inode, cp_reason, datasync, ret);return ret; }@@ -246,10 +248,10 @@ static int f2fs_do_sync_file(struct file *file, loff_t start, loff_t end,* sudden-power-off. */ down_read (&F2FS_I (inode)->i_sem); - need_cp =need_do_checkpoint (inode); + cp_reason =need_do_checkpoint (inode);up_read (&F2FS_I (inode)->i_sem); -if (need_cp) { +if (cp_reason) {/* all the dirty node pages should be flushed for POR */ ret =f2fs_sync_fs (inode->i_sb,1 );@@ -306,7 +308,7 @@ static int f2fs_do_sync_file(struct file *file, loff_t start, loff_t end, }f2fs_update_time (sbi,REQ_TIME ); out: -trace_f2fs_sync_file_exit (inode, need_cp, datasync, ret); +trace_f2fs_sync_file_exit (inode, cp_reason, datasync, ret);f2fs_trace_ios (NULL ,1 );return ret; }include/trace/events/f2fs.h +6
-6@@ -210,14 +210,14 @@ DEFINE_EVENT(f2fs__inode, f2fs_sync_file_enter, TRACE_EVENT(f2fs_sync_file_exit, - TP_PROTO(struct inode *inode, int need_cp, int datasync, int ret), + TP_PROTO(struct inode *inode, int cp_reason, int datasync, int ret), - TP_ARGS(inode, need_cp, datasync, ret), + TP_ARGS(inode, cp_reason, datasync, ret), TP_STRUCT__entry( __field(dev_t, dev) __field(ino_t, ino) - __field(int, need_cp) + __field(int, cp_reason) __field(int, datasync) __field(int, ret) ),@@ -225,15 +225,15 @@ TRACE_EVENT(f2fs_sync_file_exit,TP_fast_assign ( __entry->dev = inode->i_sb->s_dev; __entry->ino = inode->i_ino; - __entry->need_cp = need_cp; + __entry->cp_reason = cp_reason; __entry->datasync = datasync; __entry->ret = ret; ), -TP_printk ("dev = (%d,%d), ino = %lu, checkpoint is %s, " +TP_printk ("dev = (%d,%d), ino = %lu, cp_reason:%d, " "datasync = %d, ret = %d" ,show_dev_ino (__entry), - __entry->need_cp ?"needed" :"not needed" , + __entry->cp_reason, __entry->datasync, __entry->ret) );Signature · 1 line
2.14.1.145.gb3622a4ee
Re: [PATCH 2/3] f2fs: trace checkpoint reason in fsync()
Quoted 47 lines · Jaegeuk Kim
Quoted 46 lines · Chao Yu
From: Chao Yu <[email protected]>
This patch slightly changes
need_do_checkpointto return the detail info that indicates why we need do checkpoint, then caller could print it with trace message.Signed-off-by Chao Yu <[email protected]>--- fs/f2fs/file.c | 34 ++++++++++++++++++---------------- include/trace/events/f2fs.h | 12 ++++++------ 2 files changed, 24 insertions(+), 22 deletions(-)fs/f2fs/file.c +10
-8@@ -141,27 +141,29 @@ static int get_parent_ino(struct inode *inode, nid_t *pino)return 1 ; } -static inline bool need_do_checkpoint (struct inode *inode) +static inline int need_do_checkpoint (struct inode *inode) {struct f2fs_sb_info *sbi =F2FS_I_SB (inode); -bool need_cp = false; +int cp_reason =0 ; -if (!S_ISREG (inode->i_mode) || inode->i_nlink !=1 ) - need_cp = true; +if (!S_ISREG (inode->i_mode)) + cp_reason =1 ; +else if (inode->i_nlink !=1 ) + cp_reason =2 ;else if (is_sbi_flag_set (sbi,SBI_NEED_CP )) - need_cp = true; + cp_reason =3 ;else if (file_wrong_pino (inode)) - need_cp = true; + cp_reason =4 ;else if (!space_for_roll_forward (sbi)) - need_cp = true; + cp_reason =5 ;else if (!is_checkpointed_node (sbi,F2FS_I (inode)->i_pino)) - need_cp = true; + cp_reason =6 ;else if (test_opt (sbi,FASTBOOT ))
Quoted 8 lines
fs/f2fs/file.c static int get_parent_ino(struct inode *inode, nid_t *pino) · line 164
Quoted 5 lines
fs/f2fs/file.c +2
-2- need_cp = true; + cp_reason =7 ; else if (sbi->active_logs == 2) - need_cp = true; + cp_reason =8 ;We need to make the numbers by enum so that we could interpret them in tracepoint below.
Agreed, could you check v2? :)
Thanks,
Quoted 95 lines
Thanks,
Quoted 89 lines
fs/f2fs/file.c +6
-6-return need_cp; +return cp_reason; }static bool need_inode_page_update (struct f2fs_sb_info *sbi,nid_t ino)@@ -196,7 +198,7 @@ static int f2fs_do_sync_file(struct file *file, loff_t start, loff_t end,struct f2fs_sb_info *sbi =F2FS_I_SB (inode);nid_t ino = inode->i_ino;int ret =0 ; -bool need_cp = false; +bool cp_reason =0 ;struct writeback_control wbc = { .sync_mode =WB_SYNC_ALL , .nr_to_write =LONG_MAX ,@@ -215,7 +217,7 @@ static int f2fs_do_sync_file(struct file *file, loff_t start, loff_t end,clear_inode_flag (inode,FI_NEED_IPU );if (ret) { -trace_f2fs_sync_file_exit (inode, need_cp, datasync, ret); +trace_f2fs_sync_file_exit (inode, cp_reason, datasync, ret);return ret; }@@ -246,10 +248,10 @@ static int f2fs_do_sync_file(struct file *file, loff_t start, loff_t end,* sudden-power-off. */ down_read (&F2FS_I (inode)->i_sem); - need_cp =need_do_checkpoint (inode); + cp_reason =need_do_checkpoint (inode);up_read (&F2FS_I (inode)->i_sem); -if (need_cp) { +if (cp_reason) {/* all the dirty node pages should be flushed for POR */ ret =f2fs_sync_fs (inode->i_sb,1 );@@ -306,7 +308,7 @@ static int f2fs_do_sync_file(struct file *file, loff_t start, loff_t end, }f2fs_update_time (sbi,REQ_TIME ); out: -trace_f2fs_sync_file_exit (inode, need_cp, datasync, ret); +trace_f2fs_sync_file_exit (inode, cp_reason, datasync, ret);f2fs_trace_ios (NULL ,1 );return ret; }include/trace/events/f2fs.h +6
-6@@ -210,14 +210,14 @@ DEFINE_EVENT(f2fs__inode, f2fs_sync_file_enter, TRACE_EVENT(f2fs_sync_file_exit, - TP_PROTO(struct inode *inode, int need_cp, int datasync, int ret), + TP_PROTO(struct inode *inode, int cp_reason, int datasync, int ret), - TP_ARGS(inode, need_cp, datasync, ret), + TP_ARGS(inode, cp_reason, datasync, ret), TP_STRUCT__entry( __field(dev_t, dev) __field(ino_t, ino) - __field(int, need_cp) + __field(int, cp_reason) __field(int, datasync) __field(int, ret) ),@@ -225,15 +225,15 @@ TRACE_EVENT(f2fs_sync_file_exit,TP_fast_assign ( __entry->dev = inode->i_sb->s_dev; __entry->ino = inode->i_ino; - __entry->need_cp = need_cp; + __entry->cp_reason = cp_reason; __entry->datasync = datasync; __entry->ret = ret; ), -TP_printk ("dev = (%d,%d), ino = %lu, checkpoint is %s, " +TP_printk ("dev = (%d,%d), ino = %lu, cp_reason:%d, " "datasync = %d, ret = %d" ,show_dev_ino (__entry), - __entry->need_cp ?"needed" :"not needed" , + __entry->cp_reason, __entry->datasync, __entry->ret) );Signature · 1 line
2.14.1.145.gb3622a4ee.
Chao Yu
maintainerPATCH 3/3 f2fs: keep isize once block is reserved cross EOF
In reply to Chao YuFrom: Chao Yu <[email protected]>
Without FADVISE_KEEP_SIZE_BIT, we will try to recover file size according to last non-hole block, so in fallocate(), we must set FADVISE_KEEP_SIZE_BIT flag once we have preallocated block cross EOF, instead of when all preallocation is success. Otherwise, file size will be incorrect due to lack of this flag.
Simple testcase to reproduce this:
1. echo 2 > /sys/fs/f2fs/<device>/inject_type
2. echo 10 > /sys/fs/f2fs/<device>/inject_rate
3. run tests/generic/392
4. disable fault injection
5. do remount
--- fs/f2fs/file.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
fs/f2fs/file.c +6 -4
@@ -1472,8 +1472,12 @@ static int expand_inode_data(struct inode *inode, loff_t offset, new_size = ((loff_t )pg_end <<PAGE_SHIFT ) + off_end; } -if (!(mode &FALLOC_FL_KEEP_SIZE ) &&i_size_read (inode) < new_size) -f2fs_i_size_write (inode, new_size); +if (new_size >i_size_read (inode)) { +if (mode &FALLOC_FL_KEEP_SIZE ) +file_set_keep_isize (inode); +else +f2fs_i_size_write (inode, new_size); + }return err; }
@@ -1520,8 +1524,6 @@ static long f2fs_fallocate(struct file *file, int mode,if (!ret) { inode->i_mtime = inode->i_ctime =current_time (inode);f2fs_mark_inode_dirty_sync (inode, false); -if (mode &FALLOC_FL_KEEP_SIZE ) -file_set_keep_isize (inode);f2fs_update_time (F2FS_I_SB (inode),REQ_TIME ); }
Signature · 1 line
2.14.1.145.gb3622a4ee
Quoted 5 lines · Chao Yu
From: Chao Yu <[email protected]>
We will keep
__add_ino_entrysuccess all the time, for ENOMEM failure case, we have already handled it with an opened loop code, so we don't have to use redundant__GFP_NOFAILinradix_tree_preload, remove it.
Why do you think an open coded allocation retry loop is better than having the MM do all it can when the nofail is requested explicitly? E.g. giving it an access to memory reserves to allow forward progress.
Quoted 45 lines
Signed-off-by Chao Yu <[email protected]>--- fs/f2fs/checkpoint.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)fs/f2fs/checkpoint.c +7
-3@@ -405,10 +405,11 @@ static void __add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, {struct inode_management *im = &sbi->im[type];struct ino_entry *e, *tmp; +bool preloaded; tmp =f2fs_kmem_cache_alloc (ino_entry_slab,GFP_NOFS ); retry: -radix_tree_preload (GFP_NOFS | __GFP_NOFAIL); + preloaded = !radix_tree_preload (GFP_NOFS );spin_lock (&im->ino_lock); e =radix_tree_lookup (&im->ino_root, ino);@@ -416,7 +417,8 @@ static void __add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, e = tmp;if (radix_tree_insert (&im->ino_root, ino, e)) {spin_unlock (&im->ino_lock); -radix_tree_preload_end (); +if (preloaded) +radix_tree_preload_end (); goto retry; }memset (e,0 ,sizeof (struct ino_entry ));@@ -431,7 +433,9 @@ static void __add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino,f2fs_set_bit (devidx, (char *)&e->dirty_device);spin_unlock (&im->ino_lock); -radix_tree_preload_end (); + +if (preloaded) +radix_tree_preload_end ();if (e != tmp)kmem_cache_free (ino_entry_slab, tmp);Signature · 1 line
2.14.1.145.gb3622a4ee
Signature · 2 lines
Michal Hocko SUSE Labs
Chao Yu
maintainerHi Michal,
Quoted 9 lines · Michal Hocko
Quoted 5 lines · Chao Yu
From: Chao Yu <[email protected]>
We will keep
__add_ino_entrysuccess all the time, for ENOMEM failure case, we have already handled it with an opened loop code, so we don't have to use redundant__GFP_NOFAILinradix_tree_preload, remove it.Why do you think an open coded allocation retry loop is better than
having the MM do all it can when the nofail is requested explicitly?> E.g. giving it an access to memory reserves to allow forward progress.
Well, just want to remove one redundant implementation. But, as you said MM has done lots of work to grab free memory including accessing memory reserves, I think it's not bad for f2fs to use this flag instead of opened loop code. :)
BTW, I notice the comments of __GFP_NOFAIL, what does this mean?
* Using this flag for costly allocations is _highly_ discouraged.
Thanks,
Quoted 47 lines
Quoted 46 lines
Signed-off-by Chao Yu <[email protected]>--- fs/f2fs/checkpoint.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)fs/f2fs/checkpoint.c +7
-3@@ -405,10 +405,11 @@ static void __add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, {struct inode_management *im = &sbi->im[type];struct ino_entry *e, *tmp; +bool preloaded; tmp =f2fs_kmem_cache_alloc (ino_entry_slab,GFP_NOFS ); retry: -radix_tree_preload (GFP_NOFS | __GFP_NOFAIL); + preloaded = !radix_tree_preload (GFP_NOFS );spin_lock (&im->ino_lock); e =radix_tree_lookup (&im->ino_root, ino);@@ -416,7 +417,8 @@ static void __add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, e = tmp;if (radix_tree_insert (&im->ino_root, ino, e)) {spin_unlock (&im->ino_lock); -radix_tree_preload_end (); +if (preloaded) +radix_tree_preload_end (); goto retry; }memset (e,0 ,sizeof (struct ino_entry ));@@ -431,7 +433,9 @@ static void __add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino,f2fs_set_bit (devidx, (char *)&e->dirty_device);spin_unlock (&im->ino_lock); -radix_tree_preload_end (); + +if (preloaded) +radix_tree_preload_end ();if (e != tmp)kmem_cache_free (ino_entry_slab, tmp);Signature · 1 line
2.14.1.145.gb3622a4ee
On Tue 07-11-17 00:08:25, Chao Yu wrote:
[...]
Quoted 2 lines
BTW, I notice the comments of
__GFP_NOFAIL, what does this mean?
* Using this flag for costly allocations is _highly_ discouraged.
This means that using __GFP_NOFAIL for high order allocations (especially those with order > PAGE_ALLOC_COSTLY_ORDER) are highly discouraged because we those are quite hard to get and looping inside the allocator basically for ever is not a wise thing to do. That being said replacing __GFP_NOFAIL by an open coded retry loop might make sense for those e.g. to check signals or other termination conditions.
Signature · 2 lines
Michal Hocko SUSE Labs
Chao Yu
maintainerQuoted 11 lines · Michal Hocko
On Tue 07-11-17 00:08:25, Chao Yu wrote:
[...]Quoted 2 lines
BTW, I notice the comments of
__GFP_NOFAIL, what does this mean?
* Using this flag for costly allocations is _highly_ discouraged.This means that using
__GFP_NOFAILfor high order allocations (especially those with order >PAGE_ALLOC_COSTLY_ORDER) are highly discouraged because we those are quite hard to get and looping inside the allocator basically for ever is not a wise thing to do. That being said replacing__GFP_NOFAILby an open coded retry loop might make sense for those e.g. to check signals or other termination conditions.
Clear to me now, thanks for your explanation and review. :)
Anyway, let me update this patch.
Thanks,
Quoted 1 line
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot