aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-09-12 19:11:45 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-09-12 19:11:45 -0400
commit48efe453e6b29561f78a1df55c7f58375259cb8c (patch)
tree53d6ac1f2010b102c15b264b13fc4c98ba634d48 /include
parentac4de9543aca59f2b763746647577302fbedd57e (diff)
parent2999ee7fda3f670effbfa746164c525f9d1be4b8 (diff)
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending
Pull SCSI target updates from Nicholas Bellinger: "Lots of activity again this round for I/O performance optimizations (per-cpu IDA pre-allocation for vhost + iscsi/target), and the addition of new fabric independent features to target-core (COMPARE_AND_WRITE + EXTENDED_COPY). The main highlights include: - Support for iscsi-target login multiplexing across individual network portals - Generic Per-cpu IDA logic (kent + akpm + clameter) - Conversion of vhost to use per-cpu IDA pre-allocation for descriptors, SGLs and userspace page pointer list - Conversion of iscsi-target + iser-target to use per-cpu IDA pre-allocation for descriptors - Add support for generic COMPARE_AND_WRITE (AtomicTestandSet) emulation for virtual backend drivers - Add support for generic EXTENDED_COPY (CopyOffload) emulation for virtual backend drivers. - Add support for fast memory registration mode to iser-target (Vu) The patches to add COMPARE_AND_WRITE and EXTENDED_COPY support are of particular significance, which make us the first and only open source target to support the full set of VAAI primitives. Currently Linux clients are lacking upstream support to actually utilize these primitives. However, with server side support now in place for folks like MKP + ZAB working on the client, this logic once reserved for the highest end of storage arrays, can now be run in VMs on their laptops" * 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (50 commits) target/iscsi: Bump versions to v4.1.0 target: Update copyright ownership/year information to 2013 iscsi-target: Bump default TCP listen backlog to 256 target: Fix >= v3.9+ regression in PR APTPL + ALUA metadata write-out iscsi-target; Bump default CmdSN Depth to 64 iscsi-target: Remove unnecessary wait_for_completion in iscsi_get_thread_set iscsi-target: Add thread_set->ts_activate_sem + use common deallocate iscsi-target: Fix race with thread_pre_handler flush_signals + ISCSI_THREAD_SET_DIE target: remove unused including <linux/version.h> iser-target: introduce fast memory registration mode (FRWR) iser-target: generalize rdma memory registration and cleanup iser-target: move rdma wr processing to a shared function target: Enable global EXTENDED_COPY setup/release target: Add Third Party Copy (3PC) bit in INQUIRY response target: Enable EXTENDED_COPY setup in spc_parse_cdb target: Add support for EXTENDED_COPY copy offload emulation target: Avoid non-existent tg_pt_gp_mem in target_alua_state_check target: Add global device list for EXTENDED_COPY target: Make helpers non static for EXTENDED_COPY command setup target: Make spc_parse_naa_6h_vendor_specific non static ...
Diffstat (limited to 'include')
-rw-r--r--include/linux/percpu_ida.h60
-rw-r--r--include/scsi/scsi.h1
-rw-r--r--include/target/iscsi/iscsi_transport.h8
-rw-r--r--include/target/target_core_backend.h7
-rw-r--r--include/target/target_core_base.h26
-rw-r--r--include/target/target_core_fabric.h30
6 files changed, 128 insertions, 4 deletions
diff --git a/include/linux/percpu_ida.h b/include/linux/percpu_ida.h
new file mode 100644
index 000000000000..0b23edbee309
--- /dev/null
+++ b/include/linux/percpu_ida.h
@@ -0,0 +1,60 @@
1#ifndef __PERCPU_IDA_H__
2#define __PERCPU_IDA_H__
3
4#include <linux/types.h>
5#include <linux/bitops.h>
6#include <linux/init.h>
7#include <linux/spinlock_types.h>
8#include <linux/wait.h>
9#include <linux/cpumask.h>
10
11struct percpu_ida_cpu;
12
13struct percpu_ida {
14 /*
15 * number of tags available to be allocated, as passed to
16 * percpu_ida_init()
17 */
18 unsigned nr_tags;
19
20 struct percpu_ida_cpu __percpu *tag_cpu;
21
22 /*
23 * Bitmap of cpus that (may) have tags on their percpu freelists:
24 * steal_tags() uses this to decide when to steal tags, and which cpus
25 * to try stealing from.
26 *
27 * It's ok for a freelist to be empty when its bit is set - steal_tags()
28 * will just keep looking - but the bitmap _must_ be set whenever a
29 * percpu freelist does have tags.
30 */
31 cpumask_t cpus_have_tags;
32
33 struct {
34 spinlock_t lock;
35 /*
36 * When we go to steal tags from another cpu (see steal_tags()),
37 * we want to pick a cpu at random. Cycling through them every
38 * time we steal is a bit easier and more or less equivalent:
39 */
40 unsigned cpu_last_stolen;
41
42 /* For sleeping on allocation failure */
43 wait_queue_head_t wait;
44
45 /*
46 * Global freelist - it's a stack where nr_free points to the
47 * top
48 */
49 unsigned nr_free;
50 unsigned *freelist;
51 } ____cacheline_aligned_in_smp;
52};
53
54int percpu_ida_alloc(struct percpu_ida *pool, gfp_t gfp);
55void percpu_ida_free(struct percpu_ida *pool, unsigned tag);
56
57void percpu_ida_destroy(struct percpu_ida *pool);
58int percpu_ida_init(struct percpu_ida *pool, unsigned long nr_tags);
59
60#endif /* __PERCPU_IDA_H__ */
diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h
index d477bfb73fb9..66d42edfb3fc 100644
--- a/include/scsi/scsi.h
+++ b/include/scsi/scsi.h
@@ -144,6 +144,7 @@ enum scsi_timeouts {
144#define ACCESS_CONTROL_IN 0x86 144#define ACCESS_CONTROL_IN 0x86
145#define ACCESS_CONTROL_OUT 0x87 145#define ACCESS_CONTROL_OUT 0x87
146#define READ_16 0x88 146#define READ_16 0x88
147#define COMPARE_AND_WRITE 0x89
147#define WRITE_16 0x8a 148#define WRITE_16 0x8a
148#define READ_ATTRIBUTE 0x8c 149#define READ_ATTRIBUTE 0x8c
149#define WRITE_ATTRIBUTE 0x8d 150#define WRITE_ATTRIBUTE 0x8d
diff --git a/include/target/iscsi/iscsi_transport.h b/include/target/iscsi/iscsi_transport.h
index e5d09d242ba3..a12589c4ee92 100644
--- a/include/target/iscsi/iscsi_transport.h
+++ b/include/target/iscsi/iscsi_transport.h
@@ -6,13 +6,13 @@ struct iscsit_transport {
6#define ISCSIT_TRANSPORT_NAME 16 6#define ISCSIT_TRANSPORT_NAME 16
7 char name[ISCSIT_TRANSPORT_NAME]; 7 char name[ISCSIT_TRANSPORT_NAME];
8 int transport_type; 8 int transport_type;
9 int priv_size;
9 struct module *owner; 10 struct module *owner;
10 struct list_head t_node; 11 struct list_head t_node;
11 int (*iscsit_setup_np)(struct iscsi_np *, struct __kernel_sockaddr_storage *); 12 int (*iscsit_setup_np)(struct iscsi_np *, struct __kernel_sockaddr_storage *);
12 int (*iscsit_accept_np)(struct iscsi_np *, struct iscsi_conn *); 13 int (*iscsit_accept_np)(struct iscsi_np *, struct iscsi_conn *);
13 void (*iscsit_free_np)(struct iscsi_np *); 14 void (*iscsit_free_np)(struct iscsi_np *);
14 void (*iscsit_free_conn)(struct iscsi_conn *); 15 void (*iscsit_free_conn)(struct iscsi_conn *);
15 struct iscsi_cmd *(*iscsit_alloc_cmd)(struct iscsi_conn *, gfp_t);
16 int (*iscsit_get_login_rx)(struct iscsi_conn *, struct iscsi_login *); 16 int (*iscsit_get_login_rx)(struct iscsi_conn *, struct iscsi_login *);
17 int (*iscsit_put_login_tx)(struct iscsi_conn *, struct iscsi_login *, u32); 17 int (*iscsit_put_login_tx)(struct iscsi_conn *, struct iscsi_login *, u32);
18 int (*iscsit_immediate_queue)(struct iscsi_conn *, struct iscsi_cmd *, int); 18 int (*iscsit_immediate_queue)(struct iscsi_conn *, struct iscsi_cmd *, int);
@@ -22,6 +22,11 @@ struct iscsit_transport {
22 int (*iscsit_queue_status)(struct iscsi_conn *, struct iscsi_cmd *); 22 int (*iscsit_queue_status)(struct iscsi_conn *, struct iscsi_cmd *);
23}; 23};
24 24
25static inline void *iscsit_priv_cmd(struct iscsi_cmd *cmd)
26{
27 return (void *)(cmd + 1);
28}
29
25/* 30/*
26 * From iscsi_target_transport.c 31 * From iscsi_target_transport.c
27 */ 32 */
@@ -92,3 +97,4 @@ extern int iscsit_tmr_post_handler(struct iscsi_cmd *, struct iscsi_conn *);
92extern struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *, gfp_t); 97extern struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *, gfp_t);
93extern int iscsit_sequence_cmd(struct iscsi_conn *, struct iscsi_cmd *, 98extern int iscsit_sequence_cmd(struct iscsi_conn *, struct iscsi_cmd *,
94 unsigned char *, __be32); 99 unsigned char *, __be32);
100extern void iscsit_release_cmd(struct iscsi_cmd *);
diff --git a/include/target/target_core_backend.h b/include/target/target_core_backend.h
index ffa2696d64dc..5ebe21cd5d1c 100644
--- a/include/target/target_core_backend.h
+++ b/include/target/target_core_backend.h
@@ -39,7 +39,8 @@ struct se_subsystem_api {
39}; 39};
40 40
41struct sbc_ops { 41struct sbc_ops {
42 sense_reason_t (*execute_rw)(struct se_cmd *cmd); 42 sense_reason_t (*execute_rw)(struct se_cmd *cmd, struct scatterlist *,
43 u32, enum dma_data_direction);
43 sense_reason_t (*execute_sync_cache)(struct se_cmd *cmd); 44 sense_reason_t (*execute_sync_cache)(struct se_cmd *cmd);
44 sense_reason_t (*execute_write_same)(struct se_cmd *cmd); 45 sense_reason_t (*execute_write_same)(struct se_cmd *cmd);
45 sense_reason_t (*execute_write_same_unmap)(struct se_cmd *cmd); 46 sense_reason_t (*execute_write_same_unmap)(struct se_cmd *cmd);
@@ -73,6 +74,10 @@ int transport_set_vpd_ident(struct t10_vpd *, unsigned char *);
73/* core helpers also used by command snooping in pscsi */ 74/* core helpers also used by command snooping in pscsi */
74void *transport_kmap_data_sg(struct se_cmd *); 75void *transport_kmap_data_sg(struct se_cmd *);
75void transport_kunmap_data_sg(struct se_cmd *); 76void transport_kunmap_data_sg(struct se_cmd *);
77/* core helpers also used by xcopy during internal command setup */
78int target_alloc_sgl(struct scatterlist **, unsigned int *, u32, bool);
79sense_reason_t transport_generic_map_mem_to_cmd(struct se_cmd *,
80 struct scatterlist *, u32, struct scatterlist *, u32);
76 81
77void array_free(void *array, int n); 82void array_free(void *array, int n);
78 83
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index e34fc904f2e1..5bdb8b7d2a69 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -5,11 +5,12 @@
5#include <linux/configfs.h> 5#include <linux/configfs.h>
6#include <linux/dma-mapping.h> 6#include <linux/dma-mapping.h>
7#include <linux/blkdev.h> 7#include <linux/blkdev.h>
8#include <linux/percpu_ida.h>
8#include <scsi/scsi_cmnd.h> 9#include <scsi/scsi_cmnd.h>
9#include <net/sock.h> 10#include <net/sock.h>
10#include <net/tcp.h> 11#include <net/tcp.h>
11 12
12#define TARGET_CORE_MOD_VERSION "v4.1.0-rc2-ml" 13#define TARGET_CORE_MOD_VERSION "v4.1.0"
13#define TARGET_CORE_VERSION TARGET_CORE_MOD_VERSION 14#define TARGET_CORE_VERSION TARGET_CORE_MOD_VERSION
14 15
15/* Maximum Number of LUNs per Target Portal Group */ 16/* Maximum Number of LUNs per Target Portal Group */
@@ -96,6 +97,10 @@
96 * block/blk-lib.c:blkdev_issue_discard() 97 * block/blk-lib.c:blkdev_issue_discard()
97 */ 98 */
98#define DA_EMULATE_TPWS 0 99#define DA_EMULATE_TPWS 0
100/* Emulation for CompareAndWrite (AtomicTestandSet) by default */
101#define DA_EMULATE_CAW 1
102/* Emulation for 3rd Party Copy (ExtendedCopy) by default */
103#define DA_EMULATE_3PC 1
99/* No Emulation for PSCSI by default */ 104/* No Emulation for PSCSI by default */
100#define DA_EMULATE_ALUA 0 105#define DA_EMULATE_ALUA 0
101/* Enforce SCSI Initiator Port TransportID with 'ISID' for PR */ 106/* Enforce SCSI Initiator Port TransportID with 'ISID' for PR */
@@ -158,6 +163,9 @@ enum se_cmd_flags_table {
158 SCF_ALUA_NON_OPTIMIZED = 0x00008000, 163 SCF_ALUA_NON_OPTIMIZED = 0x00008000,
159 SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC = 0x00020000, 164 SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC = 0x00020000,
160 SCF_ACK_KREF = 0x00040000, 165 SCF_ACK_KREF = 0x00040000,
166 SCF_COMPARE_AND_WRITE = 0x00080000,
167 SCF_COMPARE_AND_WRITE_POST = 0x00100000,
168 SCF_CMD_XCOPY_PASSTHROUGH = 0x00200000,
161}; 169};
162 170
163/* struct se_dev_entry->lun_flags and struct se_lun->lun_access */ 171/* struct se_dev_entry->lun_flags and struct se_lun->lun_access */
@@ -196,6 +204,7 @@ enum tcm_sense_reason_table {
196 TCM_ADDRESS_OUT_OF_RANGE = R(0x11), 204 TCM_ADDRESS_OUT_OF_RANGE = R(0x11),
197 TCM_OUT_OF_RESOURCES = R(0x12), 205 TCM_OUT_OF_RESOURCES = R(0x12),
198 TCM_PARAMETER_LIST_LENGTH_ERROR = R(0x13), 206 TCM_PARAMETER_LIST_LENGTH_ERROR = R(0x13),
207 TCM_MISCOMPARE_VERIFY = R(0x14),
199#undef R 208#undef R
200}; 209};
201 210
@@ -415,6 +424,8 @@ struct se_cmd {
415 enum dma_data_direction data_direction; 424 enum dma_data_direction data_direction;
416 /* For SAM Task Attribute */ 425 /* For SAM Task Attribute */
417 int sam_task_attr; 426 int sam_task_attr;
427 /* Used for se_sess->sess_tag_pool */
428 unsigned int map_tag;
418 /* Transport protocol dependent state, see transport_state_table */ 429 /* Transport protocol dependent state, see transport_state_table */
419 enum transport_state_table t_state; 430 enum transport_state_table t_state;
420 unsigned cmd_wait_set:1; 431 unsigned cmd_wait_set:1;
@@ -444,11 +455,14 @@ struct se_cmd {
444 struct kref cmd_kref; 455 struct kref cmd_kref;
445 struct target_core_fabric_ops *se_tfo; 456 struct target_core_fabric_ops *se_tfo;
446 sense_reason_t (*execute_cmd)(struct se_cmd *); 457 sense_reason_t (*execute_cmd)(struct se_cmd *);
447 void (*transport_complete_callback)(struct se_cmd *); 458 sense_reason_t (*execute_rw)(struct se_cmd *, struct scatterlist *,
459 u32, enum dma_data_direction);
460 sense_reason_t (*transport_complete_callback)(struct se_cmd *);
448 461
449 unsigned char *t_task_cdb; 462 unsigned char *t_task_cdb;
450 unsigned char __t_task_cdb[TCM_MAX_COMMAND_SIZE]; 463 unsigned char __t_task_cdb[TCM_MAX_COMMAND_SIZE];
451 unsigned long long t_task_lba; 464 unsigned long long t_task_lba;
465 unsigned int t_task_nolb;
452 unsigned int transport_state; 466 unsigned int transport_state;
453#define CMD_T_ABORTED (1 << 0) 467#define CMD_T_ABORTED (1 << 0)
454#define CMD_T_ACTIVE (1 << 1) 468#define CMD_T_ACTIVE (1 << 1)
@@ -469,7 +483,9 @@ struct se_cmd {
469 struct work_struct work; 483 struct work_struct work;
470 484
471 struct scatterlist *t_data_sg; 485 struct scatterlist *t_data_sg;
486 struct scatterlist *t_data_sg_orig;
472 unsigned int t_data_nents; 487 unsigned int t_data_nents;
488 unsigned int t_data_nents_orig;
473 void *t_data_vmap; 489 void *t_data_vmap;
474 struct scatterlist *t_bidi_data_sg; 490 struct scatterlist *t_bidi_data_sg;
475 unsigned int t_bidi_data_nents; 491 unsigned int t_bidi_data_nents;
@@ -536,6 +552,8 @@ struct se_session {
536 struct list_head sess_wait_list; 552 struct list_head sess_wait_list;
537 spinlock_t sess_cmd_lock; 553 spinlock_t sess_cmd_lock;
538 struct kref sess_kref; 554 struct kref sess_kref;
555 void *sess_cmd_map;
556 struct percpu_ida sess_tag_pool;
539}; 557};
540 558
541struct se_device; 559struct se_device;
@@ -589,6 +607,8 @@ struct se_dev_attrib {
589 int emulate_tas; 607 int emulate_tas;
590 int emulate_tpu; 608 int emulate_tpu;
591 int emulate_tpws; 609 int emulate_tpws;
610 int emulate_caw;
611 int emulate_3pc;
592 int enforce_pr_isids; 612 int enforce_pr_isids;
593 int is_nonrot; 613 int is_nonrot;
594 int emulate_rest_reord; 614 int emulate_rest_reord;
@@ -656,6 +676,7 @@ struct se_device {
656 spinlock_t se_port_lock; 676 spinlock_t se_port_lock;
657 spinlock_t se_tmr_lock; 677 spinlock_t se_tmr_lock;
658 spinlock_t qf_cmd_lock; 678 spinlock_t qf_cmd_lock;
679 struct semaphore caw_sem;
659 /* Used for legacy SPC-2 reservationsa */ 680 /* Used for legacy SPC-2 reservationsa */
660 struct se_node_acl *dev_reserved_node_acl; 681 struct se_node_acl *dev_reserved_node_acl;
661 /* Used for ALUA Logical Unit Group membership */ 682 /* Used for ALUA Logical Unit Group membership */
@@ -669,6 +690,7 @@ struct se_device {
669 struct list_head delayed_cmd_list; 690 struct list_head delayed_cmd_list;
670 struct list_head state_list; 691 struct list_head state_list;
671 struct list_head qf_cmd_list; 692 struct list_head qf_cmd_list;
693 struct list_head g_dev_node;
672 /* Pointer to associated SE HBA */ 694 /* Pointer to associated SE HBA */
673 struct se_hba *se_hba; 695 struct se_hba *se_hba;
674 /* T10 Inquiry and VPD WWN Information */ 696 /* T10 Inquiry and VPD WWN Information */
diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h
index 7a16178424f9..882b650e32be 100644
--- a/include/target/target_core_fabric.h
+++ b/include/target/target_core_fabric.h
@@ -84,6 +84,9 @@ struct target_core_fabric_ops {
84}; 84};
85 85
86struct se_session *transport_init_session(void); 86struct se_session *transport_init_session(void);
87int transport_alloc_session_tags(struct se_session *, unsigned int,
88 unsigned int);
89struct se_session *transport_init_session_tags(unsigned int, unsigned int);
87void __transport_register_session(struct se_portal_group *, 90void __transport_register_session(struct se_portal_group *,
88 struct se_node_acl *, struct se_session *, void *); 91 struct se_node_acl *, struct se_session *, void *);
89void transport_register_session(struct se_portal_group *, 92void transport_register_session(struct se_portal_group *,
@@ -131,6 +134,7 @@ int core_tmr_alloc_req(struct se_cmd *, void *, u8, gfp_t);
131void core_tmr_release_req(struct se_tmr_req *); 134void core_tmr_release_req(struct se_tmr_req *);
132int transport_generic_handle_tmr(struct se_cmd *); 135int transport_generic_handle_tmr(struct se_cmd *);
133void transport_generic_request_failure(struct se_cmd *, sense_reason_t); 136void transport_generic_request_failure(struct se_cmd *, sense_reason_t);
137void __target_execute_cmd(struct se_cmd *);
134int transport_lookup_tmr_lun(struct se_cmd *, u32); 138int transport_lookup_tmr_lun(struct se_cmd *, u32);
135 139
136struct se_node_acl *core_tpg_check_initiator_node_acl(struct se_portal_group *, 140struct se_node_acl *core_tpg_check_initiator_node_acl(struct se_portal_group *,
@@ -175,4 +179,30 @@ u32 iscsi_get_pr_transport_id_len(struct se_portal_group *, struct se_node_acl *
175char *iscsi_parse_pr_out_transport_id(struct se_portal_group *, const char *, 179char *iscsi_parse_pr_out_transport_id(struct se_portal_group *, const char *,
176 u32 *, char **); 180 u32 *, char **);
177 181
182/*
183 * The LIO target core uses DMA_TO_DEVICE to mean that data is going
184 * to the target (eg handling a WRITE) and DMA_FROM_DEVICE to mean
185 * that data is coming from the target (eg handling a READ). However,
186 * this is just the opposite of what we have to tell the DMA mapping
187 * layer -- eg when handling a READ, the HBA will have to DMA the data
188 * out of memory so it can send it to the initiator, which means we
189 * need to use DMA_TO_DEVICE when we map the data.
190 */
191static inline enum dma_data_direction
192target_reverse_dma_direction(struct se_cmd *se_cmd)
193{
194 if (se_cmd->se_cmd_flags & SCF_BIDI)
195 return DMA_BIDIRECTIONAL;
196
197 switch (se_cmd->data_direction) {
198 case DMA_TO_DEVICE:
199 return DMA_FROM_DEVICE;
200 case DMA_FROM_DEVICE:
201 return DMA_TO_DEVICE;
202 case DMA_NONE:
203 default:
204 return DMA_NONE;
205 }
206}
207
178#endif /* TARGET_CORE_FABRICH */ 208#endif /* TARGET_CORE_FABRICH */