On 06/16/2017 09:59 AM, Jens Axboe wrote: > On 06/16/2017 09:52 AM, Christoph Hellwig wrote: >> On Fri, Jun 16, 2017 at 08:35:07AM -0600, Jens Axboe wrote: >>>> Agreed. In fact I'd go a little further: we should have a >>>> >>>> u16 hints; >>>> >>>> that goes all the way down from fcntl to the driver, right now >>>> we'll allocate the first 3 bits for the write lifetime hints (2.5, >>>> so we have one value spare, as they don't need to flags but can be >>>> enum values), leaving more space for other kinds of hints. >>> >>> Did you see v5? It adds enum write_hint and passes it all the way down, >>> until we transform them into rq/bio flags. >> >> Yes. But with all the way down I mean all the way down to the driver :) > > Only missing part is the request flags. And why make that any different > than the flags we already have now? It'd be trivial to pack the value > into the request flags as well, but I'm struggling to see the point of > that, honestly. > > Please expand on why you think changing the request flags to also > carry that value would be useful, as opposed to just mapping it when > we setup the request. If you have a valid concern I don't mind making > the change, but I just don't see one right now. So that would look like the below change on top of the current v5. I skipped the callers, since those are all easy s/bio_op_write_hint/write_hint_to_opf changes. diff --git a/block/bio.c b/block/bio.c index 758d83d91bb0..888e7801c638 100644 --- a/block/bio.c +++ b/block/bio.c @@ -2082,22 +2082,6 @@ void bio_clone_blkcg_association(struct bio *dst, struct bio *src) #endif /* CONFIG_BLK_CGROUP */ -static const unsigned int rwf_write_to_opf_flag[] = { - 0, REQ_WRITE_SHORT, REQ_WRITE_MEDIUM, REQ_WRITE_LONG, REQ_WRITE_EXTREME -}; - -/* - * Convert WRITE_LIFE_* hints into req/bio flags - */ -unsigned int bio_op_write_hint(enum write_hint hint) -{ - if (WARN_ON_ONCE(hint >= ARRAY_SIZE(rwf_write_to_opf_flag))) - return 0; - - return rwf_write_to_opf_flag[hint]; -} -EXPORT_SYMBOL_GPL(bio_op_write_hint); - static void __init biovec_init_slabs(void) { int i; diff --git a/include/linux/bio.h b/include/linux/bio.h index e9360dc5ea07..d1b04b0e99cf 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -443,7 +443,6 @@ extern struct bio *bio_copy_kern(struct request_queue *, void *, unsigned int, gfp_t, int); extern void bio_set_pages_dirty(struct bio *bio); extern void bio_check_pages_dirty(struct bio *bio); -extern unsigned int bio_op_write_hint(enum write_hint hint); void generic_start_io_acct(int rw, unsigned long sectors, struct hd_struct *part); diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index 23646eb433e7..f4d348cd3a6b 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h @@ -7,6 +7,7 @@ #include <linux/types.h> #include <linux/bvec.h> +#include <linux/fs.h> struct bio_set; struct bio; @@ -201,10 +202,9 @@ enum req_flag_bits { __REQ_PREFLUSH, /* request for cache flush */ __REQ_RAHEAD, /* read ahead, can fail anytime */ __REQ_BACKGROUND, /* background IO */ - __REQ_WRITE_SHORT, /* short life time write */ - __REQ_WRITE_MEDIUM, /* medium life time write */ - __REQ_WRITE_LONG, /* long life time write */ - __REQ_WRITE_EXTREME, /* extremely long life time write */ + __REQ_WRITE_HINT_SHIFT, /* 3 bits for life time hint */ + __REQ_WRITE_HINT_PAD1, + __REQ_WRITE_HINT_PAD2, /* command specific flags for REQ_OP_WRITE_ZEROES: */ __REQ_NOUNMAP, /* do not free blocks when zeroing */ @@ -225,13 +225,12 @@ enum req_flag_bits { #define REQ_PREFLUSH (1ULL << __REQ_PREFLUSH) #define REQ_RAHEAD (1ULL << __REQ_RAHEAD) #define REQ_BACKGROUND (1ULL << __REQ_BACKGROUND) -#define REQ_WRITE_SHORT (1ULL << __REQ_WRITE_SHORT) -#define REQ_WRITE_MEDIUM (1ULL << __REQ_WRITE_MEDIUM) -#define REQ_WRITE_LONG (1ULL << __REQ_WRITE_LONG) -#define REQ_WRITE_EXTREME (1ULL << __REQ_WRITE_EXTREME) +#define REQ_WRITE_SHORT (WRITE_HINT_SHORT << __REQ_WRITE_HINT_SHIFT) +#define REQ_WRITE_MEDIUM (WRITE_HINT_MEDIUM << __REQ_WRITE_HINT_SHIFT) +#define REQ_WRITE_LONG (WRITE_HINT_LONG << __REQ_WRITE_HINT_SHIFT) +#define REQ_WRITE_EXTREME (WRITE_HINT_EXTREME << __REQ_WRITE_HINT_SHIFT) -#define REQ_WRITE_LIFE_MASK (REQ_WRITE_SHORT | REQ_WRITE_MEDIUM | \ - REQ_WRITE_LONG | REQ_WRITE_EXTREME) +#define REQ_WRITE_LIFE_MASK (0x7 << __REQ_WRITE_HINT_SHIFT) #define REQ_NOUNMAP (1ULL << __REQ_NOUNMAP) @@ -328,4 +327,9 @@ static inline bool op_write_hint_valid(unsigned int opf) return (opf & REQ_WRITE_LIFE_MASK) != 0; } +static inline unsigned int write_hint_to_opf(enum write_hint hint) +{ + return hint << __REQ_WRITE_HINT_SHIFT; +} + #endif /* __LINUX_BLK_TYPES_H */ -- Jens Axboe