1fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda/* 2fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda * Copyright (C) 2004-2005 IBM Corp. All Rights Reserved. 3fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda * Copyright (C) 2006-2009 NEC Corporation. 4fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda * 5fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda * dm-queue-length.c 6fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda * 7fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda * Module Author: Stefan Bader, IBM 8fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda * Modified by: Kiyoshi Ueda, NEC 9fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda * 10fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda * This file is released under the GPL. 11fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda * 12fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda * queue-length path selector - choose a path with the least number of 13fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda * in-flight I/Os. 14fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda */ 15fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 16fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda#include "dm.h" 17fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda#include "dm-path-selector.h" 18fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 19fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda#include <linux/slab.h> 20fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda#include <linux/ctype.h> 21fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda#include <linux/errno.h> 22fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda#include <linux/module.h> 2360063497a95e716c9a689af3be2687d261f115b4Arun Sharma#include <linux/atomic.h> 24fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 25fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda#define DM_MSG_PREFIX "multipath queue-length" 26fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda#define QL_MIN_IO 128 27fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda#define QL_VERSION "0.1.0" 28fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 29fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Uedastruct selector { 30fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda struct list_head valid_paths; 31fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda struct list_head failed_paths; 32fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda}; 33fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 34fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Uedastruct path_info { 35fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda struct list_head list; 36fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda struct dm_path *path; 37fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda unsigned repeat_count; 38fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda atomic_t qlen; /* the number of in-flight I/Os */ 39fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda}; 40fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 41fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Uedastatic struct selector *alloc_selector(void) 42fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda{ 43fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda struct selector *s = kmalloc(sizeof(*s), GFP_KERNEL); 44fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 45fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda if (s) { 46fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda INIT_LIST_HEAD(&s->valid_paths); 47fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda INIT_LIST_HEAD(&s->failed_paths); 48fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda } 49fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 50fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda return s; 51fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda} 52fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 53fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Uedastatic int ql_create(struct path_selector *ps, unsigned argc, char **argv) 54fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda{ 55fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda struct selector *s = alloc_selector(); 56fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 57fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda if (!s) 58fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda return -ENOMEM; 59fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 60fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda ps->context = s; 61fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda return 0; 62fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda} 63fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 64fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Uedastatic void ql_free_paths(struct list_head *paths) 65fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda{ 66fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda struct path_info *pi, *next; 67fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 68fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda list_for_each_entry_safe(pi, next, paths, list) { 69fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda list_del(&pi->list); 70fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda kfree(pi); 71fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda } 72fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda} 73fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 74fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Uedastatic void ql_destroy(struct path_selector *ps) 75fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda{ 76fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda struct selector *s = ps->context; 77fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 78fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda ql_free_paths(&s->valid_paths); 79fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda ql_free_paths(&s->failed_paths); 80fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda kfree(s); 81fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda ps->context = NULL; 82fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda} 83fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 84fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Uedastatic int ql_status(struct path_selector *ps, struct dm_path *path, 85fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda status_type_t type, char *result, unsigned maxlen) 86fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda{ 87fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda unsigned sz = 0; 88fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda struct path_info *pi; 89fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 90fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda /* When called with NULL path, return selector status/args. */ 91fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda if (!path) 92fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda DMEMIT("0 "); 93fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda else { 94fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda pi = path->pscontext; 95fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 96fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda switch (type) { 97fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda case STATUSTYPE_INFO: 98fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda DMEMIT("%d ", atomic_read(&pi->qlen)); 99fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda break; 100fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda case STATUSTYPE_TABLE: 101fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda DMEMIT("%u ", pi->repeat_count); 102fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda break; 103fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda } 104fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda } 105fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 106fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda return sz; 107fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda} 108fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 109fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Uedastatic int ql_add_path(struct path_selector *ps, struct dm_path *path, 110fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda int argc, char **argv, char **error) 111fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda{ 112fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda struct selector *s = ps->context; 113fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda struct path_info *pi; 114fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda unsigned repeat_count = QL_MIN_IO; 11531998ef19385c944600d9a981b96252f98204beeMikulas Patocka char dummy; 116fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 117fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda /* 118fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda * Arguments: [<repeat_count>] 119fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda * <repeat_count>: The number of I/Os before switching path. 120fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda * If not given, default (QL_MIN_IO) is used. 121fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda */ 122fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda if (argc > 1) { 123fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda *error = "queue-length ps: incorrect number of arguments"; 124fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda return -EINVAL; 125fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda } 126fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 12731998ef19385c944600d9a981b96252f98204beeMikulas Patocka if ((argc == 1) && (sscanf(argv[0], "%u%c", &repeat_count, &dummy) != 1)) { 128fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda *error = "queue-length ps: invalid repeat count"; 129fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda return -EINVAL; 130fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda } 131fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 132fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda /* Allocate the path information structure */ 133fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda pi = kmalloc(sizeof(*pi), GFP_KERNEL); 134fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda if (!pi) { 135fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda *error = "queue-length ps: Error allocating path information"; 136fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda return -ENOMEM; 137fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda } 138fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 139fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda pi->path = path; 140fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda pi->repeat_count = repeat_count; 141fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda atomic_set(&pi->qlen, 0); 142fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 143fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda path->pscontext = pi; 144fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 145fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda list_add_tail(&pi->list, &s->valid_paths); 146fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 147fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda return 0; 148fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda} 149fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 150fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Uedastatic void ql_fail_path(struct path_selector *ps, struct dm_path *path) 151fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda{ 152fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda struct selector *s = ps->context; 153fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda struct path_info *pi = path->pscontext; 154fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 155fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda list_move(&pi->list, &s->failed_paths); 156fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda} 157fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 158fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Uedastatic int ql_reinstate_path(struct path_selector *ps, struct dm_path *path) 159fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda{ 160fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda struct selector *s = ps->context; 161fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda struct path_info *pi = path->pscontext; 162fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 163fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda list_move_tail(&pi->list, &s->valid_paths); 164fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 165fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda return 0; 166fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda} 167fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 168fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda/* 169fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda * Select a path having the minimum number of in-flight I/Os 170fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda */ 171fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Uedastatic struct dm_path *ql_select_path(struct path_selector *ps, 172fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda unsigned *repeat_count, size_t nr_bytes) 173fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda{ 174fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda struct selector *s = ps->context; 175fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda struct path_info *pi = NULL, *best = NULL; 176fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 177fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda if (list_empty(&s->valid_paths)) 178fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda return NULL; 179fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 180fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda /* Change preferred (first in list) path to evenly balance. */ 181fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda list_move_tail(s->valid_paths.next, &s->valid_paths); 182fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 183fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda list_for_each_entry(pi, &s->valid_paths, list) { 184fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda if (!best || 185fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda (atomic_read(&pi->qlen) < atomic_read(&best->qlen))) 186fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda best = pi; 187fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 188fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda if (!atomic_read(&best->qlen)) 189fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda break; 190fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda } 191fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 192fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda if (!best) 193fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda return NULL; 194fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 195fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda *repeat_count = best->repeat_count; 196fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 197fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda return best->path; 198fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda} 199fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 200fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Uedastatic int ql_start_io(struct path_selector *ps, struct dm_path *path, 201fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda size_t nr_bytes) 202fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda{ 203fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda struct path_info *pi = path->pscontext; 204fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 205fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda atomic_inc(&pi->qlen); 206fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 207fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda return 0; 208fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda} 209fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 210fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Uedastatic int ql_end_io(struct path_selector *ps, struct dm_path *path, 211fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda size_t nr_bytes) 212fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda{ 213fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda struct path_info *pi = path->pscontext; 214fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 215fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda atomic_dec(&pi->qlen); 216fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 217fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda return 0; 218fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda} 219fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 220fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Uedastatic struct path_selector_type ql_ps = { 221fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda .name = "queue-length", 222fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda .module = THIS_MODULE, 223fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda .table_args = 1, 224fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda .info_args = 1, 225fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda .create = ql_create, 226fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda .destroy = ql_destroy, 227fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda .status = ql_status, 228fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda .add_path = ql_add_path, 229fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda .fail_path = ql_fail_path, 230fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda .reinstate_path = ql_reinstate_path, 231fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda .select_path = ql_select_path, 232fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda .start_io = ql_start_io, 233fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda .end_io = ql_end_io, 234fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda}; 235fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 236fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Uedastatic int __init dm_ql_init(void) 237fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda{ 238fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda int r = dm_register_path_selector(&ql_ps); 239fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 240fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda if (r < 0) 241fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda DMERR("register failed %d", r); 242fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 243fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda DMINFO("version " QL_VERSION " loaded"); 244fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 245fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda return r; 246fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda} 247fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 248fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Uedastatic void __exit dm_ql_exit(void) 249fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda{ 250fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda int r = dm_unregister_path_selector(&ql_ps); 251fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 252fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda if (r < 0) 253fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda DMERR("unregister failed %d", r); 254fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda} 255fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 256fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Uedamodule_init(dm_ql_init); 257fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Uedamodule_exit(dm_ql_exit); 258fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda 259fd5e033908b7b743b5650790f196761dd930f988Kiyoshi UedaMODULE_AUTHOR("Stefan Bader <Stefan.Bader at de.ibm.com>"); 260fd5e033908b7b743b5650790f196761dd930f988Kiyoshi UedaMODULE_DESCRIPTION( 261fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda "(C) Copyright IBM Corp. 2004,2005 All Rights Reserved.\n" 262fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda DM_NAME " path selector to balance the number of in-flight I/Os" 263fd5e033908b7b743b5650790f196761dd930f988Kiyoshi Ueda); 264fd5e033908b7b743b5650790f196761dd930f988Kiyoshi UedaMODULE_LICENSE("GPL"); 265