Skip to content
Snippets Groups Projects
Select Git revision
  • 02ab823fd1a27d193bda06b74fdad685a20a3e5e
  • seco_lf-6.6.52-2.2.1 default protected
  • integrate/gitlab-ci/use-board-only-instead-codename-and-board-in-the-configuration/into/seco_lf-5.10.y
  • integrate/gitlab-ci/oleksii/fix-mtk-misc-artifacts/into/seco_lf-6.6.52-2.2.1
  • seco_lf-6.6.52-2.2.1-tr8mp-dtb
  • seco_lf-6.6.52-2.2.1-tr8mp-fpga
  • integrate/gitlab-ci/use-board-only-instead-codename-and-board-in-the-configuration/into/seco_lf-6.6.52-2.2.1
  • seco_lf-6.6.52-2.2.1-tr8mp-rv3028
  • seco_lf-6.6.52-2.2.1-tr8mp-mcu
  • seco_lf-6.6.23-2.0.0_e39-e83-p4-devicetree
  • integrate/gitlab-ci/cleaos-894-rename-distros-into-build-tergets/into/seco_lf-5.10.y
  • integrate/gitlab-ci/cleaos-894-rename-distros-into-build-tergets/into/seco_lf-6.6.52-2.2.1
  • seco_lf-5.10.y protected
  • seco_lf-6.6.52-2.2.1_e88-dev
  • seco_lf-6.6.52-2.2.1_ov5640-mx95-dev
  • seco_lf-6.6.52-2.2.1-tr8mp-rgb-defconfig
  • seco_lf-6.6.52-2.2.1-tr8mp-dev
  • seco_lf-6.6.52-2.2.1-tr8mp-dtbo
  • seco_lf-6.6.52-2.2.1_stm32g0-dev
  • seco_lf-6.6.52-2.2.1_remove-mwifiex_d18
  • seco_lf-6.6.52-2.2.1_e88-dbg-uart-dev
  • lf-6.6.52-2.2.1
  • lf-6.1.55-2.2.1
  • lf-6.6.3-1.0.0
  • lf-6.6.3-imx95-er2
  • lf-6.1.55-2.2.0
  • lf-6.6.y-imx95-er1
  • lf-5.15.71-2.2.2
  • lf-6.1.36-2.1.0
  • lf-5.15.71-2.2.1
  • lf-6.1.22-2.0.0
  • lf-6.1.1-1.0.1
  • rel_imx_5.4.24_2.1.4
  • rel_imx_4.9.88_2.0.13
  • rel_imx_4.14.98_2.3.5
  • lf-6.1.1-1.0.0
  • rel_imx_5.4.3_2.0.2
  • lf-5.15.71-2.2.0
  • lf-5.10.72-2.2.3
  • lf-5.15.52-2.1.0
  • imx_5.15.52_imx8ulp_er1
41 results

dm-round-robin.c

Blame
  • user avatar
    Kiyoshi Ueda authored and Alasdair G Kergon committed
    This patch makes two additions to the dm path selector interface for
    dynamic load balancers:
      o a new hook, start_io()
      o a new parameter 'nr_bytes' to select_path()/start_io()/end_io()
        to pass the size of the I/O
    
    start_io() is called when a target driver actually submits I/O
    to the selected path.
    Path selectors can use it to start accounting of the I/O.
    (e.g. counting the number of in-flight I/Os.)
    The start_io hook is based on the patch posted by Stefan Bader:
    https://www.redhat.com/archives/dm-devel/2005-October/msg00050.html
    
    
    
    nr_bytes, the size of the I/O, is so path selectors can take the
    size of the I/O into account when deciding which path to use.
    dm-service-time uses it to estimate service time, for example.
    (Added the nr_bytes member to dm_mpath_io instead of using existing
     details.bi_size, since request-based dm patch deletes it.)
    
    Signed-off-by: default avatarStefan Bader <stefan.bader@canonical.com>
    Signed-off-by: default avatarKiyoshi Ueda <k-ueda@ct.jp.nec.com>
    Signed-off-by: default avatarJun'ichi Nomura <j-nomura@ce.jp.nec.com>
    Signed-off-by: default avatarAlasdair G Kergon <agk@redhat.com>
    02ab823f
    History
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    dm-round-robin.c 4.56 KiB
    /*
     * Copyright (C) 2003 Sistina Software.
     * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
     *
     * Module Author: Heinz Mauelshagen
     *
     * This file is released under the GPL.
     *
     * Round-robin path selector.
     */
    
    #include <linux/device-mapper.h>
    
    #include "dm-path-selector.h"
    
    #include <linux/slab.h>
    
    #define DM_MSG_PREFIX "multipath round-robin"
    
    /*-----------------------------------------------------------------
     * Path-handling code, paths are held in lists
     *---------------------------------------------------------------*/
    struct path_info {
    	struct list_head list;
    	struct dm_path *path;
    	unsigned repeat_count;
    };
    
    static void free_paths(struct list_head *paths)
    {
    	struct path_info *pi, *next;
    
    	list_for_each_entry_safe(pi, next, paths, list) {
    		list_del(&pi->list);
    		kfree(pi);
    	}
    }
    
    /*-----------------------------------------------------------------
     * Round-robin selector
     *---------------------------------------------------------------*/
    
    #define RR_MIN_IO		1000
    
    struct selector {
    	struct list_head valid_paths;
    	struct list_head invalid_paths;
    };
    
    static struct selector *alloc_selector(void)
    {
    	struct selector *s = kmalloc(sizeof(*s), GFP_KERNEL);
    
    	if (s) {
    		INIT_LIST_HEAD(&s->valid_paths);
    		INIT_LIST_HEAD(&s->invalid_paths);
    	}
    
    	return s;
    }
    
    static int rr_create(struct path_selector *ps, unsigned argc, char **argv)
    {
    	struct selector *s;
    
    	s = alloc_selector();
    	if (!s)
    		return -ENOMEM;
    
    	ps->context = s;
    	return 0;
    }
    
    static void rr_destroy(struct path_selector *ps)
    {
    	struct selector *s = (struct selector *) ps->context;
    
    	free_paths(&s->valid_paths);
    	free_paths(&s->invalid_paths);
    	kfree(s);
    	ps->context = NULL;
    }
    
    static int rr_status(struct path_selector *ps, struct dm_path *path,
    		     status_type_t type, char *result, unsigned int maxlen)
    {
    	struct path_info *pi;
    	int sz = 0;
    
    	if (!path)
    		DMEMIT("0 ");
    	else {
    		switch(type) {
    		case STATUSTYPE_INFO:
    			break;
    		case STATUSTYPE_TABLE:
    			pi = path->pscontext;
    			DMEMIT("%u ", pi->repeat_count);
    			break;
    		}
    	}
    
    	return sz;
    }
    
    /*
     * Called during initialisation to register each path with an
     * optional repeat_count.
     */
    static int rr_add_path(struct path_selector *ps, struct dm_path *path,
    		       int argc, char **argv, char **error)
    {
    	struct selector *s = (struct selector *) ps->context;
    	struct path_info *pi;
    	unsigned repeat_count = RR_MIN_IO;
    
    	if (argc > 1) {
    		*error = "round-robin ps: incorrect number of arguments";
    		return -EINVAL;
    	}
    
    	/* First path argument is number of I/Os before switching path */
    	if ((argc == 1) && (sscanf(argv[0], "%u", &repeat_count) != 1)) {
    		*error = "round-robin ps: invalid repeat count";
    		return -EINVAL;
    	}
    
    	/* allocate the path */
    	pi = kmalloc(sizeof(*pi), GFP_KERNEL);
    	if (!pi) {
    		*error = "round-robin ps: Error allocating path context";
    		return -ENOMEM;
    	}
    
    	pi->path = path;
    	pi->repeat_count = repeat_count;
    
    	path->pscontext = pi;
    
    	list_add_tail(&pi->list, &s->valid_paths);
    
    	return 0;
    }
    
    static void rr_fail_path(struct path_selector *ps, struct dm_path *p)
    {
    	struct selector *s = (struct selector *) ps->context;
    	struct path_info *pi = p->pscontext;
    
    	list_move(&pi->list, &s->invalid_paths);
    }
    
    static int rr_reinstate_path(struct path_selector *ps, struct dm_path *p)
    {
    	struct selector *s = (struct selector *) ps->context;
    	struct path_info *pi = p->pscontext;
    
    	list_move(&pi->list, &s->valid_paths);
    
    	return 0;
    }
    
    static struct dm_path *rr_select_path(struct path_selector *ps,
    				      unsigned *repeat_count, size_t nr_bytes)
    {
    	struct selector *s = (struct selector *) ps->context;
    	struct path_info *pi = NULL;
    
    	if (!list_empty(&s->valid_paths)) {
    		pi = list_entry(s->valid_paths.next, struct path_info, list);
    		list_move_tail(&pi->list, &s->valid_paths);
    		*repeat_count = pi->repeat_count;
    	}
    
    	return pi ? pi->path : NULL;
    }
    
    static struct path_selector_type rr_ps = {
    	.name = "round-robin",
    	.module = THIS_MODULE,
    	.table_args = 1,
    	.info_args = 0,
    	.create = rr_create,
    	.destroy = rr_destroy,
    	.status = rr_status,
    	.add_path = rr_add_path,
    	.fail_path = rr_fail_path,
    	.reinstate_path = rr_reinstate_path,
    	.select_path = rr_select_path,
    };
    
    static int __init dm_rr_init(void)
    {
    	int r = dm_register_path_selector(&rr_ps);
    
    	if (r < 0)
    		DMERR("register failed %d", r);
    
    	DMINFO("version 1.0.0 loaded");
    
    	return r;
    }
    
    static void __exit dm_rr_exit(void)
    {
    	int r = dm_unregister_path_selector(&rr_ps);
    
    	if (r < 0)
    		DMERR("unregister failed %d", r);
    }
    
    module_init(dm_rr_init);
    module_exit(dm_rr_exit);
    
    MODULE_DESCRIPTION(DM_NAME " round-robin multipath path selector");
    MODULE_AUTHOR("Sistina Software <dm-devel@redhat.com>");
    MODULE_LICENSE("GPL");