OpenVZ Forum


Home » Mailing lists » Devel » [PATCH 0/2] dm-band: The I/O bandwidth controller: Overview
[PATCH 1/2] dm-band: The I/O bandwidth controller: Source code patch [message #26440 is a reply to message #26434] Wed, 23 January 2008 12:56 Go to previous messageGo to previous message
Ryo Tsuruta is currently offline  Ryo Tsuruta
Messages: 35
Registered: January 2008
Member
Here is the patch of dm-band.

Based on 2.6.23.14
Signed-off-by: Ryo Tsuruta <ryov@valinux.co.jp>
Signed-off-by: Hirokazu Takahashi <taka@valinux.co.jp>

diff -uprN linux-2.6.23.14.orig/drivers/md/Kconfig linux-2.6.23.14/drivers/md/Kconfig
--- linux-2.6.23.14.orig/drivers/md/Kconfig	2008-01-15 05:49:56.000000000 +0900
+++ linux-2.6.23.14/drivers/md/Kconfig	2008-01-21 16:09:41.000000000 +0900
@@ -276,4 +276,13 @@ config DM_DELAY
 
 	If unsure, say N.
 
+config DM_BAND
+	tristate "I/O band width control "
+	depends on BLK_DEV_DM
+	---help---
+	Any processes or cgroups can use the same storage
+	with its band-width fairly shared.
+
+	If unsure, say N.
+
 endif # MD
diff -uprN linux-2.6.23.14.orig/drivers/md/Makefile linux-2.6.23.14/drivers/md/Makefile
--- linux-2.6.23.14.orig/drivers/md/Makefile	2008-01-15 05:49:56.000000000 +0900
+++ linux-2.6.23.14/drivers/md/Makefile	2008-01-21 20:45:03.000000000 +0900
@@ -8,6 +8,7 @@ dm-multipath-objs := dm-hw-handler.o dm-
 dm-snapshot-objs := dm-snap.o dm-exception-store.o
 dm-mirror-objs	:= dm-log.o dm-raid1.o
 dm-rdac-objs	:= dm-mpath-rdac.o
+dm-band-objs	:= dm-bandctl.o dm-band-policy.o dm-band-type.o
 md-mod-objs     := md.o bitmap.o
 raid456-objs	:= raid5.o raid6algos.o raid6recov.o raid6tables.o \
 		   raid6int1.o raid6int2.o raid6int4.o \
@@ -39,6 +40,7 @@ obj-$(CONFIG_DM_MULTIPATH_RDAC)	+= dm-rd
 obj-$(CONFIG_DM_SNAPSHOT)	+= dm-snapshot.o
 obj-$(CONFIG_DM_MIRROR)		+= dm-mirror.o
 obj-$(CONFIG_DM_ZERO)		+= dm-zero.o
+obj-$(CONFIG_DM_BAND)		+= dm-band.o
 
 quiet_cmd_unroll = UNROLL  $@
       cmd_unroll = $(PERL) $(srctree)/$(src)/unroll.pl $(UNROLL) \
diff -uprN linux-2.6.23.14.orig/drivers/md/dm-band-policy.c linux-2.6.23.14/drivers/md/dm-band-policy.c
--- linux-2.6.23.14.orig/drivers/md/dm-band-policy.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.23.14/drivers/md/dm-band-policy.c	2008-01-21 20:31:14.000000000 +0900
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2008 VA Linux Systems Japan K.K.
+ *
+ *  I/O bandwidth control
+ *
+ * This file is released under the GPL.
+ */
+#include <linux/bio.h>
+#include <linux/workqueue.h>
+#include "dm.h"
+#include "dm-bio-list.h"
+#include "dm-band.h"
+
+/*
+ * The following functiotons determine when and which BIOs should
+ * be submitted to control the I/O flow.
+ * It is possible to add a new I/O scheduling policy with it.
+ */
+
+
+/*
+ * Functions for weight balancing policy.
+ */
+#define DEFAULT_WEIGHT	100
+#define DEFAULT_TOKENBASE	2048
+#define BAND_IOPRIO_BASE 100
+
+static int proceed_global_epoch(struct banddevice *bs)
+{
+	bs->g_epoch++;
+#if 0	/* this will also work correct */
+	if (bs->g_blocked)
+		queue_work(bs->g_band_wq, &bs->g_conductor);
+	return 0;
+#endif
+	dprintk(KERN_ERR "proceed_epoch %d --> %d\n",
+						bs->g_epoch-1, bs->g_epoch);
+	return 1;
+}
+
+static inline int proceed_epoch(struct bandgroup *bw)
+{
+	struct banddevice *bs = bw->c_shared;
+
+	if (bw->c_my_epoch != bs->g_epoch) {
+		bw->c_my_epoch = bs->g_epoch;
+		return 1;
+	}
+	return 0;
+}
+
+static inline int iopriority(struct bandgroup *bw)
+{
+	struct banddevice *bs = bw->c_shared;
+	int iopri;
+
+	iopri = bw->c_token*BAND_IOPRIO_BASE/bw->c_token_init_value + 1;
+	if (bw->c_my_epoch != bs->g_epoch)
+		iopri += BAND_IOPRIO_BASE;
+	if (bw->c_going_down)
+		iopri += BAND_IOPRIO_BASE*2;
+
+	return iopri;
+}
+
+static int is_token_left(struct bandgroup *bw)
+{
+	if (bw->c_token > 0)
+		return iopriority(bw);
+
+	if (proceed_epoch(bw) || bw->c_going_down) {
+		bw->c_token = bw->c_token_init_value;
+		dprintk(KERN_ERR "refill token: bw:%p token:%d\n",
+							bw, bw->c_token);
+		return iopriority(bw);
+	}
+	return 0;
+}
+
+static void prepare_token(struct bandgroup *bw, struct bio *bio)
+{
+	bw->c_token--;
+}
+
+static void set_weight(struct bandgroup *bw, int new)
+{
+	struct banddevice *bs = bw->c_shared;
+	struct bandgroup *p;
+
+	bs->g_weight_total += (new - bw->c_weight);
+	bw->c_weight = new;
+
+	list_for_each_entry(p, &bs->g_brothers, c_list) {
+		/* Fixme: it might overflow */
+		p->c_token = p->c_token_init_value =
+		   bs->g_token_base*p->c_weight/bs->g_weight_total + 1;
+	}
+}
+
+static int policy_weight_ctr(struct bandgroup *bw)
+{
+	struct banddevice *bs = bw->c_shared;
+
+	bw->c_my_epoch = bs->g_epoch;
+	bw->c_weight = 0;
+	set_weight(bw, DEFAULT_WEIGHT);
+	return 0;
+}
+
+static void policy_weight_dtr(struct bandgroup *bw)
+{
+	set_weight(bw, 0);
+}
+
+static int policy_weight_param(struct bandgroup *bw, char *cmd, char *value)
+{
+	struct banddevice *bs = bw->c_shared;
+	int val = simple_strtol(value, NULL, 0);
+	int r = 0;
+
+	if (!strcmp(cmd, "weight")) {
+		if (val > 0)
+			set_weight(bw, val);
+		else
+			r = -EINVAL;
+	} else if (!strcmp(cmd, "token")) {
+		if (val > 0) {
+			bs->g_token_base = val;
+			set_weight(bw, bw->c_weight);
+		} else
+			r = -EINVAL;
+	} else {
+		r = -EINVAL;
+	}
+	return r;
+}
+
+/*
+ *  <Method>      <description>
+ * g_can_submit   : To determine whether a given group has a right to
+ *                  submit BIOs.
+ * 		    The larger return value the higher priority to submit.
+ * 		    Zero means it has no right.
+ * g_prepare_bio  : Called right before submitting each BIO.
+ * g_restart_bios : Called when there exist some BIOs blocked but none of them
+ * 		    can't be submitted now.
+ *		    This method have to do something to restart to submit BIOs.
+ * 		    Returns 0 if it has become able to submit them now.
+ * 		    Otherwise, returns 1 and this policy module has to restart
+ *		    sumitting BIOs by itself later on.
+ * g_hold_bio     : To hold a given BIO until it is submitted.
+ * 		    The default function is used when this method is undefined.
+ * g_pop_bio      : To select and get the best BIO to submit.
+ * g_group_ctr    : To initalize the policy own members of struct bandgroup.
+ * g_group_dtr    : Called when struct bandgroup is removed.
+ * g_set_param    : To update the policy own date.
+ * 		    The parameters can be passed through "dmsetup message"
+ *                  command.
+ */
+static void policy_weight_init(struct banddevice *bs)
+{
+	bs->g_can_submit = is_token_left;
+	bs->g_prepare_bio = prepare_token;
+	bs->g_restart_bios = proceed_global_epoch;
+	bs->g_group_ctr = policy_weight_ctr;
+	bs->g_group_dtr = policy_weight_dtr;
+	bs->g_set_param = policy_weight_param;
+
+	bs->g_token_base = DEFAULT_TOKENBASE;
+	bs->g_epoch = 0;
+	bs->g_weight_total = 0;
+}
+/* weight balancing policy. --- End --- */
+
+
+static void policy_default_init(struct banddevice *bs) /*XXX*/
+{
+	policy_weight_init(bs);	/* temp */
+}
+
+struct policy_type band_policy_type[] = {
+	{"default", policy_default_init},
+	{"weight", policy_weight_init},
+	{NULL,     policy_default_init}
+};
diff -uprN linux-2.6.23.14.orig/drivers/md/dm-band-type.c linux-2.6.23.14/drivers/md/dm-band-type.c
--- linux-2.6.23.14.orig/drivers/md/dm-band-type.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.23.14/drivers/md/dm-band-type.c	2008-01-21 20:27:15.000000000 +0900
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2008 VA Linux Systems Japan K.K.
+ *
+ *  I/O bandwidth control
+ *
+ * This file is released under the GPL.
+ */
+#include <linux/bio.h>
+#include "dm.h"
+#include "dm-bio-list.h"
+#include "dm-band.h"
+
+/*
+ * Any I/O bandwidth can be divided into several bandwidth groups, each of which
+ * has its own unique ID. The following functions are called to determine
+ * which group a given BIO belongs to and return the ID of the group.
+ */
+
+/* ToDo: unsigned long value would be better for group ID */
+
+static int band_process_id(struct bio *bio)
+{
+	/*
+	 * This function will work for KVM and Xen.
+	 */
+	return (int)current->tgid;
+}
+
+static int band_process_group(struct bio *bio)
+{
+	return (int)process_group(current);
+}
+
+static int band_uid(struct bio *bio)
+{
+	return (int)current->uid;
+}
+
+static int band_cpuset(struct bio *bio)
+{
+	return 0;	/* not implemented yet */
+}
+
+static int band_node(struct bio *bio)
+{
+	return 0;	/* not implemented yet */
+}
+
+static int band_cgroup(struct bio *bio)
+{
+  /*
+   * This function should return the ID of the cgroup which issued "bio".
+   * The ID of the cgroup which the current process belongs to won't be
+   * suitable ID for this purpose, since some BIOs will be handled by kernel
+   * threads like aio or pdflush on behalf of the process requesting the BIOs.
+   */
+	return 0;	/* not implemented yet */
+}
+
+struct group_type band_group_type[] = {
+	{"none",   NULL},
+	{"pgrp",   band_process_group},
+	{"pid",    band_process_id},
+	{"node",   band_node},
+	{"cpuset", band_cpuset},
+	{"cgroup", band_cgroup},
+	{"user",   band_uid},
+	{NULL,     NULL}
+};
diff -uprN linux-2.6.23.14.orig/drivers/md/dm-band.h linux-2.6.23.14/drivers/md/dm-band.h
--- linux-2.6.23.14.orig/drivers/md/dm-band.h	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.23.14/drivers/md/dm-band.h	2008-01-21 20:20:54.000000000 +0900
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2008 VA Linux Systems Japan K.K.
+ *
+ *  I/O bandwidth control
+ *
+ * This file is released under the GPL.
+ */
+
+#define DEFAULT_IO_THROTTLE	4
+#define DEFAULT_IO_LIMIT	128
+#define BAND_NAME_MAX 31
+#define BAND_ID_ANY (-1)
+
+struct bandgroup;
+
+struct banddevice {
+	struct list_head	g_brothers;
+	struct work_struct	g_conductor;
+	struct workqueue_struct	*g_band_wq;
+	int	g_io_throttle;
+	int	g_io_limit;
+	int	g_plug_bio;
+	int	g_issued;
+	int	g_blocked;
+	spinlock_t	g_lock;
+
+	int	g_devgroup;
+	int	g_ref;		/* just for debugging */
+	struct	list_head g_list;
+	int	g_flags;	/*
...

 
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Previous Topic: [PATCH 4/4] Get rid of the kill_pgrp_info() function
Next Topic: Re: [PATCH 6/12] gfs2: make gfs2_glock.gl_owner_pid be a struct pid *
Goto Forum:
  


Current Time: Fri Aug 16 19:52:15 GMT 2024

Total time taken to generate the page: 0.03778 seconds