Commit 3f3aad5e authored by Roger Pau Monne's avatar Roger Pau Monne Committed by Konrad Rzeszutek Wilk

xen-blkback: implement LRU mechanism for persistent grants

This mechanism allows blkback to change the number of grants
persistently mapped at run time.

The algorithm uses a simple LRU mechanism that removes (if needed) the
persistent grants that have not been used since the last LRU run, or
if all grants have been used it removes the first grants in the list
(that are not in use).

The algorithm allows the user to change the maximum number of
persistent grants, by changing max_persistent_grants in sysfs.

Since we are storing the persistent grants used inside the request
struct (to be able to mark them as "unused" when unmapping), we no
longer need the bitmap (unmap_seg).
Signed-off-by: default avatarRoger Pau Monné <roger.pau@citrix.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: xen-devel@lists.xen.org
Signed-off-by: default avatarKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
parent c6cc142d
...@@ -81,3 +81,13 @@ Contact: Roger Pau Monné <roger.pau@citrix.com> ...@@ -81,3 +81,13 @@ Contact: Roger Pau Monné <roger.pau@citrix.com>
Description: Description:
Maximum number of free pages to keep in each block Maximum number of free pages to keep in each block
backend buffer. backend buffer.
What: /sys/module/xen_blkback/parameters/max_persistent_grants
Date: March 2013
KernelVersion: 3.10
Contact: Roger Pau Monné <roger.pau@citrix.com>
Description:
Maximum number of grants to map persistently in
blkback. If the frontend tries to use more than
max_persistent_grants, the LRU kicks in and starts
removing 5% of max_persistent_grants every 100ms.
This diff is collapsed.
...@@ -182,12 +182,23 @@ struct xen_vbd { ...@@ -182,12 +182,23 @@ struct xen_vbd {
struct backend_info; struct backend_info;
/* Number of available flags */
#define PERSISTENT_GNT_FLAGS_SIZE 2
/* This persistent grant is currently in use */
#define PERSISTENT_GNT_ACTIVE 0
/*
* This persistent grant has been used, this flag is set when we remove the
* PERSISTENT_GNT_ACTIVE, to know that this grant has been used recently.
*/
#define PERSISTENT_GNT_WAS_ACTIVE 1
struct persistent_gnt { struct persistent_gnt {
struct page *page; struct page *page;
grant_ref_t gnt; grant_ref_t gnt;
grant_handle_t handle; grant_handle_t handle;
DECLARE_BITMAP(flags, PERSISTENT_GNT_FLAGS_SIZE);
struct rb_node node; struct rb_node node;
struct list_head remove_node;
}; };
struct xen_blkif { struct xen_blkif {
...@@ -219,6 +230,12 @@ struct xen_blkif { ...@@ -219,6 +230,12 @@ struct xen_blkif {
/* tree to store persistent grants */ /* tree to store persistent grants */
struct rb_root persistent_gnts; struct rb_root persistent_gnts;
unsigned int persistent_gnt_c; unsigned int persistent_gnt_c;
atomic_t persistent_gnt_in_use;
unsigned long next_lru;
/* used by the kworker that offload work from the persistent purge */
struct list_head persistent_purge_list;
struct work_struct persistent_purge_work;
/* buffer of free pages to map grant refs */ /* buffer of free pages to map grant refs */
spinlock_t free_pages_lock; spinlock_t free_pages_lock;
...@@ -262,6 +279,7 @@ int xen_blkif_xenbus_init(void); ...@@ -262,6 +279,7 @@ int xen_blkif_xenbus_init(void);
irqreturn_t xen_blkif_be_int(int irq, void *dev_id); irqreturn_t xen_blkif_be_int(int irq, void *dev_id);
int xen_blkif_schedule(void *arg); int xen_blkif_schedule(void *arg);
int xen_blkif_purge_persistent(void *arg);
int xen_blkbk_flush_diskcache(struct xenbus_transaction xbt, int xen_blkbk_flush_diskcache(struct xenbus_transaction xbt,
struct backend_info *be, int state); struct backend_info *be, int state);
......
...@@ -98,6 +98,7 @@ static void xen_update_blkif_status(struct xen_blkif *blkif) ...@@ -98,6 +98,7 @@ static void xen_update_blkif_status(struct xen_blkif *blkif)
err = PTR_ERR(blkif->xenblkd); err = PTR_ERR(blkif->xenblkd);
blkif->xenblkd = NULL; blkif->xenblkd = NULL;
xenbus_dev_error(blkif->be->dev, err, "start xenblkd"); xenbus_dev_error(blkif->be->dev, err, "start xenblkd");
return;
} }
} }
...@@ -121,6 +122,7 @@ static struct xen_blkif *xen_blkif_alloc(domid_t domid) ...@@ -121,6 +122,7 @@ static struct xen_blkif *xen_blkif_alloc(domid_t domid)
spin_lock_init(&blkif->free_pages_lock); spin_lock_init(&blkif->free_pages_lock);
INIT_LIST_HEAD(&blkif->free_pages); INIT_LIST_HEAD(&blkif->free_pages);
blkif->free_pages_num = 0; blkif->free_pages_num = 0;
atomic_set(&blkif->persistent_gnt_in_use, 0);
return blkif; return blkif;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment