[stgt] [PATCH] Make thread per <connection/target> a user configurable option
Chandra Seetharaman
sekharan at us.ibm.com
Sat Oct 16 03:26:36 CEST 2010
Hi All,
--
Note: This applies cleanly on the thread branch on top of the patches I
sent yesterday.
--
With the thread-per-connection patches that I sent yesterday, there are
three levels of threading that can be achieved
1. No threads at all
2. One thread per target
3. One thread per connection to a target.
These are stacked up, i.e when 3 is set 2 is assumed.
This patch allows user to select one of the thread type from above. Thread
type can be specified at the time of creation of a target.
Ex:
# Do not use threads at all
# tgtadm --lld iscsi --op new --mode target --tid 1 -T mytarget.1:01 -x none
# Use Thread per target. This is default too. IOW, both the commands below
# achieve the same result.
# tgtadm --lld iscsi --op new --mode target --tid 1 -T mytarget.1:01 -x thread
# tgtadm --lld iscsi --op new --mode target --tid 1 -T mytarget.1:01
# Use one thread per connection (on top of one thread per target)
# tgtadm --lld iscsi --op new --mode target --tid 1 -T mytarget.1:01 -x conn
Signed-off-by: Chandra Seetharaman <sekharan at us.ibm.com>
---
doc/tgtadm.8.xml | 6 +++++-
usr/iscsi/iscsi_tcp.c | 48 ++++++++++++++++++++++++------------------------
usr/iscsi/iscsid.c | 8 ++++++--
usr/iscsi/iscsid.h | 2 +-
usr/iscsi/target.c | 2 +-
usr/target.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++--
usr/target.h | 2 ++
usr/tgtadm.c | 17 ++++++++++++-----
usr/tgtd.h | 6 ++++++
9 files changed, 106 insertions(+), 36 deletions(-)
Index: tgt-thread/usr/tgtd.h
===================================================================
--- tgt-thread.orig/usr/tgtd.h
+++ tgt-thread/usr/tgtd.h
@@ -32,6 +32,12 @@ enum tgt_system_state {
TGT_SYSTEM_READY,
};
+enum tgt_thread_type {
+ NO_PTHREAD = 0,
+ PTHREAD_PER_TARGET,
+ PTHREAD_PER_CONN,
+};
+
enum scsi_target_state {
SCSI_TARGET_OFFLINE = 1,
SCSI_TARGET_READY,
Index: tgt-thread/usr/target.h
===================================================================
--- tgt-thread.orig/usr/target.h
+++ tgt-thread/usr/target.h
@@ -43,6 +43,8 @@ struct target {
struct tgt_account account;
struct bs_finish *bsf;
+
+ enum tgt_thread_type thr_type;
};
struct it_nexus {
Index: tgt-thread/usr/iscsi/iscsid.h
===================================================================
--- tgt-thread.orig/usr/iscsi/iscsid.h
+++ tgt-thread/usr/iscsi/iscsid.h
@@ -331,7 +331,7 @@ int iscsi_target_update(int mode, int op
int target_redirected(struct iscsi_target *target,
struct iscsi_connection *conn, char *buf, int *reason);
-int iscsi_pthread_per_target(void);
+enum tgt_thread_type iscsi_pthread_per_target(struct target *target);
/* param.c */
int param_index_by_name(char *name, struct iscsi_key *keys);
Index: tgt-thread/usr/target.c
===================================================================
--- tgt-thread.orig/usr/target.c
+++ tgt-thread/usr/target.c
@@ -1639,6 +1639,47 @@ static char *target_state_name(enum scsi
return name;
}
+static struct {
+ enum tgt_thread_type value;
+ char *name;
+} thread_type[] = {
+ {NO_PTHREAD, "none"},
+ {PTHREAD_PER_TARGET, "target"},
+ {PTHREAD_PER_CONN, "conn"},
+};
+
+static enum tgt_thread_type target_thread_type(char *name)
+{
+ int i;
+ enum tgt_thread_type type = -1;
+
+ for (i = 0; i < ARRAY_SIZE(thread_type); i++) {
+ if (!strcmp(thread_type[i].name, name)) {
+ type = thread_type[i].value;
+ break;
+ }
+ }
+ if (type == -1) {
+ eprintf("Unknown thread type <%s>, setting to default\n", name);
+ type = PTHREAD_PER_TARGET;
+ }
+ return type;
+}
+
+static char *target_thr_type_name(enum tgt_thread_type type)
+{
+ int i;
+ char *name = NULL;
+
+ for (i = 0; i < ARRAY_SIZE(thread_type); i++) {
+ if (thread_type[i].value == type) {
+ name = thread_type[i].name;
+ break;
+ }
+ }
+ return name;
+}
+
int tgt_set_target_state(int tid, char *str)
{
int i, err = TGTADM_INVALID_REQUEST;
@@ -1720,11 +1761,13 @@ int tgt_target_show_all(char *buf, int r
"Target %d: %s\n"
_TAB1 "System information:\n"
_TAB2 "Driver: %s\n"
- _TAB2 "State: %s\n",
+ _TAB2 "State: %s\n"
+ _TAB2 "Thread type: %s\n",
target->tid,
target->name,
tgt_drivers[target->lid]->name,
- target_state_name(target->target_state));
+ target_state_name(target->target_state),
+ target_thr_type_name(target->thr_type));
shprintf(total, buf, rest, _TAB1 "I_T nexus information:\n");
@@ -1816,6 +1859,7 @@ int tgt_target_create(int lld, int tid,
struct target *target, *pos;
char *p, *q, *targetname = NULL;
struct backingstore_template *bst;
+ int type = PTHREAD_PER_TARGET;
p = args;
while ((q = strsep(&p, ","))) {
@@ -1827,6 +1871,8 @@ int tgt_target_create(int lld, int tid,
if (!strcmp("targetname", q))
targetname = str;
+ else if (!strcmp("thread", q))
+ type = target_thread_type(str);
else
eprintf("Unknow option %s\n", q);
}
@@ -1869,6 +1915,7 @@ int tgt_target_create(int lld, int tid,
target->account.max_inaccount = DEFAULT_NR_ACCOUNT;
target->tid = tid;
+ target->thr_type = type;
INIT_LIST_HEAD(&target->device_list);
Index: tgt-thread/usr/tgtadm.c
===================================================================
--- tgt-thread.orig/usr/tgtadm.c
+++ tgt-thread/usr/tgtadm.c
@@ -103,6 +103,7 @@ struct option const long_options[] = {
{"bstype", required_argument, NULL, 'E'},
{"bsoflags", required_argument, NULL, 'f'},
{"targetname", required_argument, NULL, 'T'},
+ {"thread", required_argument, NULL, 'x'},
{"initiator-address", required_argument, NULL, 'I'},
{"user", required_argument, NULL, 'u'},
{"password", required_argument, NULL, 'p'},
@@ -116,7 +117,7 @@ struct option const long_options[] = {
{NULL, 0, NULL, 0},
};
-static char *short_options = "dhL:o:m:t:s:c:l:n:v:b:E:f:T:I:u:p:H:P:B:Y:O:C:";
+static char *short_options = "dhL:o:m:t:s:c:l:n:v:b:x:E:f:T:I:u:p:H:P:B:Y:O:C:";
static void usage(int status)
{
@@ -127,7 +128,7 @@ static void usage(int status)
printf("\
Linux SCSI Target Framework Administration Utility, version %s\n\
\n\
- --lld <driver> --mode target --op new --tid <id> --targetname <name>\n\
+ --lld <driver> --mode target --op new --tid <id> --targetname <name> [ --thread <type> ]\n\
add a new target with <id> and <name>. <id> must not be zero.\n\
--lld <driver> --mode target --op delete --tid <id>\n\
delete the specific target with <id>. The target must\n\
@@ -423,7 +424,7 @@ int main(int argc, char **argv)
uint32_t cid, hostno;
uint64_t sid, lun;
char *name, *value, *path, *targetname, *params, *address, *targetOps;
- char *bstype;
+ char *bstype, *thread_type;
char *bsoflags;
char *user, *password;
char *buf;
@@ -439,7 +440,7 @@ int main(int argc, char **argv)
ac_dir = ACCOUNT_TYPE_INCOMING;
rest = BUFSIZE;
name = value = path = targetname = address = targetOps = bstype = NULL;
- bsoflags = user = password = NULL;
+ bsoflags = user = password = thread_type = NULL;
buf = valloc(bufsz);
if (!buf) {
@@ -531,6 +532,9 @@ int main(int argc, char **argv)
case 'h':
usage(0);
break;
+ case 'x':
+ thread_type = optarg;
+ break;
default:
usage(1);
}
@@ -583,7 +587,7 @@ int main(int argc, char **argv)
}
switch (op) {
case OP_NEW:
- rc = verify_mode_params(argc, argv, "LmotTC");
+ rc = verify_mode_params(argc, argv, "LmotTCx");
if (rc) {
eprintf("target mode: option '-%c' is not "
"allowed/supported\n", rc);
@@ -780,6 +784,9 @@ int main(int argc, char **argv)
if (targetname)
shprintf(total, params, rest, "%stargetname=%s",
rest == BUFSIZE ? "" : ",", targetname);
+ if (thread_type)
+ shprintf(total, params, rest, "%sthread=%s",
+ rest == BUFSIZE ? "" : ",", thread_type);
if (address)
shprintf(total, params, rest, "%sinitiator-address=%s",
rest == BUFSIZE ? "" : ",", address);
Index: tgt-thread/usr/iscsi/iscsi_tcp.c
===================================================================
--- tgt-thread.orig/usr/iscsi/iscsi_tcp.c
+++ tgt-thread/usr/iscsi/iscsi_tcp.c
@@ -35,6 +35,7 @@
#include "iscsid.h"
#include "tgtd.h"
+#include "target.h"
#include "util.h"
static void iscsi_tcp_event_handler(int fd, int events, void *data);
@@ -42,10 +43,6 @@ static void iscsi_tcp_event_handler(int
static int listen_fds[8];
static struct iscsi_transport iscsi_tcp;
-#define NO_PTHREAD 0
-#define PTHREAD_PER_TARGET 1
-#define PTHREAD_PER_CONN 2
-
struct iscsi_tcp_connection {
int fd;
int pthread;
@@ -293,32 +290,35 @@ static void iscsi_tcp_conn_nexus_init(st
{
struct iscsi_tcp_connection *tcp_conn = TCP_CONN(conn);
struct thread_info *ti;
- int ret;
+ struct target *t = target_lookup(conn->tid);
+ int ret, type;
- if (iscsi_pthread_per_target()) {
+ if ((type = iscsi_pthread_per_target(t)) != NO_PTHREAD) {
/* remove the conn from the main thread. */
tgt_event_del(tcp_conn->fd);
- ti = &conn->session->target->ti;
-
tcp_conn->pthread = PTHREAD_PER_TARGET;
+ ti = &conn->session->target->ti;
- conn->conn_ti.bsf = NULL;
- conn->conn_ti.stop_pthread = 0;
- conn->conn_ti.start_pthread = 0;
- INIT_LIST_HEAD(&conn->conn_ti.t_list);
- pthread_rwlock_init(&conn->conn_ti.rwlock, NULL);
-
- conn->conn_ti.efd = epoll_create(128);
- if (conn->conn_ti.efd < 0)
- goto thread_per_target;
-
- ret = pthread_create(&conn->thread, NULL, thread_fn, &conn->conn_ti);
- if (!ret) {
- eprintf("created thread %u for connection %p\n",
- (unsigned) conn->thread, conn);
- ti = &conn->conn_ti;
- tcp_conn->pthread = PTHREAD_PER_CONN;
+ if (type == PTHREAD_PER_CONN) {
+ conn->conn_ti.bsf = NULL;
+ conn->conn_ti.stop_pthread = 0;
+ conn->conn_ti.start_pthread = 0;
+ INIT_LIST_HEAD(&conn->conn_ti.t_list);
+ pthread_rwlock_init(&conn->conn_ti.rwlock, NULL);
+
+ conn->conn_ti.efd = epoll_create(128);
+ if (conn->conn_ti.efd < 0)
+ goto thread_per_target;
+
+ ret = pthread_create(&conn->thread, NULL,
+ thread_fn, &conn->conn_ti);
+ if (!ret) {
+ eprintf("created thread %u for connection %p\n",
+ (unsigned) conn->thread, conn);
+ ti = &conn->conn_ti;
+ tcp_conn->pthread = PTHREAD_PER_CONN;
+ }
}
thread_per_target:
do_tgt_event_add(ti, tcp_conn->fd, EPOLLIN,
Index: tgt-thread/usr/iscsi/iscsid.c
===================================================================
--- tgt-thread.orig/usr/iscsi/iscsid.c
+++ tgt-thread/usr/iscsi/iscsid.c
@@ -39,6 +39,7 @@
#include "driver.h"
#include "scsi.h"
#include "tgtadm.h"
+#include "target.h"
#include "crc32c.h"
#define MAX_QUEUE_CMD 128
@@ -76,9 +77,12 @@ enum {
int iscsi_rdma_enabled;
-int iscsi_pthread_per_target(void)
+enum tgt_thread_type iscsi_pthread_per_target(struct target *t)
{
- return sig_fd >= 0 && !iscsi_rdma_enabled;
+ if (sig_fd >= 0 && !iscsi_rdma_enabled)
+ return t->thr_type;
+ else
+ return NO_PTHREAD;
}
void conn_read_pdu(struct iscsi_connection *conn)
Index: tgt-thread/usr/iscsi/target.c
===================================================================
--- tgt-thread.orig/usr/iscsi/target.c
+++ tgt-thread/usr/iscsi/target.c
@@ -443,7 +443,7 @@ int iscsi_target_create(struct target *t
isns_target_register(tgt_targetname(tid));
- if (iscsi_pthread_per_target()) {
+ if (iscsi_pthread_per_target(t) != NO_PTHREAD) {
int ret;
INIT_LIST_HEAD(&target->ti.t_list);
Index: tgt-thread/doc/tgtadm.8.xml
===================================================================
--- tgt-thread.orig/doc/tgtadm.8.xml
+++ tgt-thread/doc/tgtadm.8.xml
@@ -21,6 +21,7 @@
<arg choice="opt">-m --mode <mode></arg>
<arg choice="opt">-t --tid <id></arg>
<arg choice="opt">-T --targetname <targetname></arg>
+ <arg choice="opt">-x --thread <thread></arg>
<arg choice="opt">-Y --device-type <type></arg>
<arg choice="opt">-l --lun <lun></arg>
<arg choice="opt">-b --backing-store <path></arg>
@@ -72,7 +73,7 @@ Possible device-types are:
changer : emulate a media changer device
</screen>
- <varlistentry><term><option>--lld <driver> --op new --mode target --tid <id> --targetname <name></option></term>
+ <varlistentry><term><option>--lld <driver> --op new --mode target --tid <id> --targetname <name> --thread <thread_type></option> </term>
<listitem>
<para>
Add a new target with <id> and <name>.
@@ -390,6 +391,9 @@ two empty DVD-R disks.
# Create a target
tgtadm --lld iscsi --mode target --op new --tid 1 --targetname iqn.2007-03:virtual-dvd:`hostname`
+# Create a target with thread type as connection. Other options are "none" and "thread"(default)
+tgtadm --lld iscsi --mode target --op new --tid 1 --targetname iqn.2007-03:virtual-dvd:`hostname` --thread conn
+
# Create a DVD drive and give it a nice name
# The dvd starts out without a backing store file, i.e. no disk loaded
tgtadm --op new --mode logicalunit --tid 1 --lun 1 --device-type cd
--
To unsubscribe from this list: send the line "unsubscribe stgt" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
More information about the stgt
mailing list