Skip to content

Commit 93a497b

Browse files
lostjeffleMiklos Szeredi
authored andcommitted
fuse: enable per inode DAX
DAX may be limited in some specific situation. When the number of usable DAX windows is under watermark, the recalim routine will be triggered to reclaim some DAX windows. It may have a negative impact on the performance, since some processes may need to wait for DAX windows to be recalimed and reused then. To mitigate the performance degradation, the overall DAX window need to be expanded larger. However, simply expanding the DAX window may not be a good deal in some scenario. To maintain one DAX window chunk (i.e., 2MB in size), 32KB (512 * 64 bytes) memory footprint will be consumed for page descriptors inside guest, which is greater than the memory footprint if it uses guest page cache when DAX disabled. Thus it'd better disable DAX for those files smaller than 32KB, to reduce the demand for DAX window and thus avoid the unworthy memory overhead. Per inode DAX feature is introduced to address this issue, by offering a finer grained control for dax to users, trying to achieve a balance between performance and memory overhead. The FUSE_ATTR_DAX flag in FUSE_LOOKUP reply is used to indicate whether DAX should be enabled or not for corresponding file. Currently the state whether DAX is enabled or not for the file is initialized only when inode is instantiated. Signed-off-by: Jeffle Xu <[email protected]> Reviewed-by: Vivek Goyal <[email protected]> Signed-off-by: Miklos Szeredi <[email protected]>
1 parent 98046f7 commit 93a497b

File tree

4 files changed

+13
-9
lines changed

4 files changed

+13
-9
lines changed

fs/fuse/dax.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1330,7 +1330,7 @@ static const struct address_space_operations fuse_dax_file_aops = {
13301330
.invalidatepage = noop_invalidatepage,
13311331
};
13321332

1333-
static bool fuse_should_enable_dax(struct inode *inode)
1333+
static bool fuse_should_enable_dax(struct inode *inode, unsigned int flags)
13341334
{
13351335
struct fuse_conn *fc = get_fuse_conn(inode);
13361336
enum fuse_dax_mode dax_mode = fc->dax_mode;
@@ -1345,12 +1345,16 @@ static bool fuse_should_enable_dax(struct inode *inode)
13451345
if (!fc->dax)
13461346
return false;
13471347

1348-
return true;
1348+
if (dax_mode == FUSE_DAX_ALWAYS)
1349+
return true;
1350+
1351+
/* dax_mode is FUSE_DAX_INODE* */
1352+
return flags & FUSE_ATTR_DAX;
13491353
}
13501354

1351-
void fuse_dax_inode_init(struct inode *inode)
1355+
void fuse_dax_inode_init(struct inode *inode, unsigned int flags)
13521356
{
1353-
if (!fuse_should_enable_dax(inode))
1357+
if (!fuse_should_enable_dax(inode, flags))
13541358
return;
13551359

13561360
inode->i_flags |= S_DAX;

fs/fuse/file.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3169,7 +3169,7 @@ static const struct address_space_operations fuse_file_aops = {
31693169
.write_end = fuse_write_end,
31703170
};
31713171

3172-
void fuse_init_file_inode(struct inode *inode)
3172+
void fuse_init_file_inode(struct inode *inode, unsigned int flags)
31733173
{
31743174
struct fuse_inode *fi = get_fuse_inode(inode);
31753175

@@ -3183,5 +3183,5 @@ void fuse_init_file_inode(struct inode *inode)
31833183
fi->writepages = RB_ROOT;
31843184

31853185
if (IS_ENABLED(CONFIG_FUSE_DAX))
3186-
fuse_dax_inode_init(inode);
3186+
fuse_dax_inode_init(inode, flags);
31873187
}

fs/fuse/fuse_i.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,7 +1025,7 @@ int fuse_notify_poll_wakeup(struct fuse_conn *fc,
10251025
/**
10261026
* Initialize file operations on a regular file
10271027
*/
1028-
void fuse_init_file_inode(struct inode *inode);
1028+
void fuse_init_file_inode(struct inode *inode, unsigned int flags);
10291029

10301030
/**
10311031
* Initialize inode operations on regular files and special files
@@ -1291,7 +1291,7 @@ int fuse_dax_conn_alloc(struct fuse_conn *fc, enum fuse_dax_mode mode,
12911291
struct dax_device *dax_dev);
12921292
void fuse_dax_conn_free(struct fuse_conn *fc);
12931293
bool fuse_dax_inode_alloc(struct super_block *sb, struct fuse_inode *fi);
1294-
void fuse_dax_inode_init(struct inode *inode);
1294+
void fuse_dax_inode_init(struct inode *inode, unsigned int flags);
12951295
void fuse_dax_inode_cleanup(struct inode *inode);
12961296
bool fuse_dax_check_alignment(struct fuse_conn *fc, unsigned int map_alignment);
12971297
void fuse_dax_cancel_work(struct fuse_conn *fc);

fs/fuse/inode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ static void fuse_init_inode(struct inode *inode, struct fuse_attr *attr)
313313
inode->i_ctime.tv_nsec = attr->ctimensec;
314314
if (S_ISREG(inode->i_mode)) {
315315
fuse_init_common(inode);
316-
fuse_init_file_inode(inode);
316+
fuse_init_file_inode(inode, attr->flags);
317317
} else if (S_ISDIR(inode->i_mode))
318318
fuse_init_dir(inode);
319319
else if (S_ISLNK(inode->i_mode))

0 commit comments

Comments
 (0)