Add BIO_SPEEDUP
Add BIO_SPEEDUP bio command and g_io_speedup wrapper. It tells the lower layers that the upper layers are dealing with some shortage (dirty pages and/or disk blocks). The lower layers should do what they can to speed up anything that's been delayed. The first use will be to tell the CAM I/O scheduler that any TRIM shaping should be short-circuited because the system needs blocks. We'll also call it when there's too many resources used by UFS. Reviewed by: kirk, kib Sponsored by: Netflix Differential Revision: https://reviews.freebsd.org/D18351
This commit is contained in:
parent
7918ea40a5
commit
b182c79211
@ -343,6 +343,7 @@ void g_io_deliver(struct bio *bp, int error);
|
||||
int g_io_getattr(const char *attr, struct g_consumer *cp, int *len, void *ptr);
|
||||
int g_io_zonecmd(struct disk_zone_args *zone_args, struct g_consumer *cp);
|
||||
int g_io_flush(struct g_consumer *cp);
|
||||
int g_io_speedup(size_t shortage, u_int flags, size_t *resid, struct g_consumer *cp);
|
||||
int g_register_classifier(struct g_classifier_hook *hook);
|
||||
void g_unregister_classifier(struct g_classifier_hook *hook);
|
||||
void g_io_request(struct bio *bp, struct g_consumer *cp);
|
||||
|
@ -340,6 +340,42 @@ g_io_zonecmd(struct disk_zone_args *zone_args, struct g_consumer *cp)
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a BIO_SPEEDUP down the stack. This is used to tell the lower layers that
|
||||
* the upper layers have detected a resource shortage. The lower layers are
|
||||
* advised to stop delaying I/O that they might be holding for performance
|
||||
* reasons and to schedule it (non-trims) or complete it successfully (trims) as
|
||||
* quickly as it can. bio_length is the amount of the shortage. This call
|
||||
* should be non-blocking. bio_resid is used to communicate back if the lower
|
||||
* layers couldn't find bio_length worth of I/O to schedule or discard. A length
|
||||
* of 0 means to do as much as you can (schedule the h/w queues full, discard
|
||||
* all trims). flags are a hint from the upper layers to the lower layers what
|
||||
* operation should be done.
|
||||
*/
|
||||
int
|
||||
g_io_speedup(size_t shortage, u_int flags, size_t *resid, struct g_consumer *cp)
|
||||
{
|
||||
struct bio *bp;
|
||||
int error;
|
||||
|
||||
KASSERT((flags & (BIO_SPEEDUP_TRIM | BIO_SPEEDUP_WRITE)) != 0,
|
||||
("Invalid flags passed to g_io_speedup: %#x", flags));
|
||||
g_trace(G_T_BIO, "bio_speedup(%s, %zu, %#x)", cp->provider->name,
|
||||
shortage, flags);
|
||||
bp = g_new_bio();
|
||||
if (bp == NULL)
|
||||
return (ENOMEM);
|
||||
bp->bio_cmd = BIO_SPEEDUP;
|
||||
bp->bio_length = shortage;
|
||||
bp->bio_done = NULL;
|
||||
bp->bio_flags |= flags;
|
||||
g_io_request(bp, cp);
|
||||
error = biowait(bp, "gflush");
|
||||
*resid = bp->bio_resid;
|
||||
g_destroy_bio(bp);
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
g_io_flush(struct g_consumer *cp)
|
||||
{
|
||||
|
@ -53,6 +53,7 @@
|
||||
#define BIO_CMD1 0x07 /* Available for local hacks */
|
||||
#define BIO_CMD2 0x08 /* Available for local hacks */
|
||||
#define BIO_ZONE 0x09 /* Zone command */
|
||||
#define BIO_SPEEDUP 0x0a /* Upper layers face shortage */
|
||||
|
||||
/* bio_flags */
|
||||
#define BIO_ERROR 0x01 /* An error occurred processing this bio. */
|
||||
@ -70,6 +71,9 @@
|
||||
#define PRINT_BIO_FLAGS "\20\7vlist\6transient_mapping\5unmapped" \
|
||||
"\4ordered\3onqueue\2done\1error"
|
||||
|
||||
#define BIO_SPEEDUP_WRITE 0x4000 /* Resource shortage at upper layers */
|
||||
#define BIO_SPEEDUP_TRIM 0x8000 /* Resource shortage at upper layers */
|
||||
|
||||
#ifdef _KERNEL
|
||||
struct disk;
|
||||
struct bio;
|
||||
|
Loading…
Reference in New Issue
Block a user