Skip to contentSkip to conversation

f2fs: split discard command in prior to block layer

PATCH Superseded Chao Yu 1 participant 1 message Aug 5, 2018 F2FS file system

v3 of 5 Superseded Latest is v5 →

lore
Share & tools
lore

Chao Yu

author maintainer
#0 lore raw

PATCH v3 1/1 f2fs: split discard command in prior to block layer

From: Chao Yu <[email protected]>

Some devices has small max_{hw,}discard_sectors, so that in __blkdev_issue_discard(), one big size discard bio can be split into multiple small size discard bios, result in heavy load in IO scheduler and device, which can hang other sync IO for long time.

Now, f2fs is trying to control discard commands more elaboratively, in order to make less conflict in between discard IO and user IO to enhance application's performance, so in this patch, we will split discard bio in f2fs in prior to in block layer to reduce issuing multiple discard bios in a short time.

---
v3:
- attach multi bios to one discard command entry.

 fs/f2fs/f2fs.h    |  14 +++----
 fs/f2fs/segment.c | 103 ++++++++++++++++++++++++++++++++--------------
 2 files changed, 78 insertions(+), 39 deletions(-)
fs/f2fs/f2fs.h +7 -7
index 1212bc4c3dbd..7f8e650c02e0 100644
@@ -178,7 +178,6 @@ enum {
 
 #define MAX_DISCARD_BLOCKS(sbi)		BLKS_PER_SEC(sbi)
 #define DEF_MAX_DISCARD_REQUEST		8	/* issue 8 discards per round */
-#define DEF_MAX_DISCARD_LEN		512	/* Max. 2MB per discard */
 #define DEF_MIN_DISCARD_ISSUE_TIME	50	/* 50 ms, if exists */
 #define DEF_MID_DISCARD_ISSUE_TIME	500	/* 500 ms, if device busy */
 #define DEF_MAX_DISCARD_ISSUE_TIME	60000	/* 60 s, if no candidates */
@@ -278,6 +277,7 @@ struct discard_cmd {
 	unsigned short ref;		/* reference count */
 	unsigned char state;		/* state */
 	int error;			/* bio error */
+	atomic_t bio_ref;		/* bio reference count */
 };
 
 enum {
@@ -710,22 +710,22 @@ static inline void set_extent_info(struct extent_info *ei, unsigned int fofs,
 }
 
 static inline bool __is_discard_mergeable(struct discard_info *back,
-						struct discard_info *front)
+			struct discard_info *front, unsigned int max_len)
 {
 	return (back->lstart + back->len == front->lstart) &&
-		(back->len + front->len < DEF_MAX_DISCARD_LEN);
+		(back->len + front->len <= max_len);
 }
 
 static inline bool __is_discard_back_mergeable(struct discard_info *cur,
-						struct discard_info *back)
+			struct discard_info *back, unsigned int max_len)
 {
-	return __is_discard_mergeable(back, cur);
+	return __is_discard_mergeable(back, cur, max_len);
 }
 
 static inline bool __is_discard_front_mergeable(struct discard_info *cur,
-						struct discard_info *front)
+			struct discard_info *front, unsigned int max_len)
 {
-	return __is_discard_mergeable(cur, front);
+	return __is_discard_mergeable(cur, front, max_len);
 }
 
 static inline bool __is_extent_mergeable(struct extent_info *back,
fs/f2fs/segment.c +71 -32

198 lines not on this page · raw message

Signature · 1 line
2.18.0