Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

target: Pass in transport supported PI at session initialization

In order to support local WRITE_INSERT + READ_STRIP operations for
non PI enabled fabrics, the fabric driver needs to be able signal
what protection offload operations are supported.

This is done at session initialization time so the modes can be
signaled by individual se_wwn + se_portal_group endpoints, as well
as optionally across different transports on the same endpoint.

For iser-target, set TARGET_PROT_ALL if the underlying ib_device
has already signaled PI offload support, and allow this to be
exposed via a new iscsit_transport->iscsit_get_sup_prot_ops()
callback.

For loopback, set TARGET_PROT_ALL to signal SCSI initiator mode
operation.

For all other drivers, set TARGET_PROT_NORMAL to disable fabric
level PI.

Cc: Martin K. Petersen <martin.petersen@oracle.com>
Cc: Sagi Grimberg <sagig@mellanox.com>
Cc: Or Gerlitz <ogerlitz@mellanox.com>
Cc: Quinn Tran <quinn.tran@qlogic.com>
Cc: Giridhar Malavali <giridhar.malavali@qlogic.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>

+52 -20
+13
drivers/infiniband/ulp/isert/ib_isert.c
··· 2196 2196 device->unreg_rdma_mem(isert_cmd, isert_conn); 2197 2197 } 2198 2198 2199 + static enum target_prot_op 2200 + isert_get_sup_prot_ops(struct iscsi_conn *conn) 2201 + { 2202 + struct isert_conn *isert_conn = (struct isert_conn *)conn->context; 2203 + struct isert_device *device = isert_conn->conn_device; 2204 + 2205 + if (device->pi_capable) 2206 + return TARGET_PROT_ALL; 2207 + 2208 + return TARGET_PROT_NORMAL; 2209 + } 2210 + 2199 2211 static int 2200 2212 isert_put_nopin(struct iscsi_cmd *cmd, struct iscsi_conn *conn, 2201 2213 bool nopout_response) ··· 3264 3252 .iscsit_queue_data_in = isert_put_datain, 3265 3253 .iscsit_queue_status = isert_put_response, 3266 3254 .iscsit_aborted_task = isert_aborted_task, 3255 + .iscsit_get_sup_prot_ops = isert_get_sup_prot_ops, 3267 3256 }; 3268 3257 3269 3258 static int __init isert_init(void)
+1 -1
drivers/infiniband/ulp/srpt/ib_srpt.c
··· 2580 2580 goto destroy_ib; 2581 2581 } 2582 2582 2583 - ch->sess = transport_init_session(); 2583 + ch->sess = transport_init_session(TARGET_PROT_NORMAL); 2584 2584 if (IS_ERR(ch->sess)) { 2585 2585 rej->reason = __constant_cpu_to_be32( 2586 2586 SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES);
+1 -1
drivers/scsi/qla2xxx/tcm_qla2xxx.c
··· 1482 1482 } 1483 1483 se_tpg = &tpg->se_tpg; 1484 1484 1485 - se_sess = transport_init_session(); 1485 + se_sess = transport_init_session(TARGET_PROT_NORMAL); 1486 1486 if (IS_ERR(se_sess)) { 1487 1487 pr_err("Unable to initialize struct se_session\n"); 1488 1488 return PTR_ERR(se_sess);
+6
drivers/target/iscsi/iscsi_target.c
··· 511 511 __iscsit_free_cmd(cmd, scsi_cmd, true); 512 512 } 513 513 514 + static enum target_prot_op iscsit_get_sup_prot_ops(struct iscsi_conn *conn) 515 + { 516 + return TARGET_PROT_NORMAL; 517 + } 518 + 514 519 static struct iscsit_transport iscsi_target_transport = { 515 520 .name = "iSCSI/TCP", 516 521 .transport_type = ISCSI_TCP, ··· 531 526 .iscsit_queue_data_in = iscsit_queue_rsp, 532 527 .iscsit_queue_status = iscsit_queue_rsp, 533 528 .iscsit_aborted_task = iscsit_aborted_task, 529 + .iscsit_get_sup_prot_ops = iscsit_get_sup_prot_ops, 534 530 }; 535 531 536 532 static int __init iscsi_target_init_module(void)
+3 -1
drivers/target/iscsi/iscsi_target_login.c
··· 259 259 { 260 260 struct iscsi_session *sess = NULL; 261 261 struct iscsi_login_req *pdu = (struct iscsi_login_req *)buf; 262 + enum target_prot_op sup_pro_ops; 262 263 int ret; 263 264 264 265 sess = kzalloc(sizeof(struct iscsi_session), GFP_KERNEL); ··· 321 320 kfree(sess); 322 321 return -ENOMEM; 323 322 } 323 + sup_pro_ops = conn->conn_transport->iscsit_get_sup_prot_ops(conn); 324 324 325 - sess->se_sess = transport_init_session(); 325 + sess->se_sess = transport_init_session(sup_pro_ops); 326 326 if (IS_ERR(sess->se_sess)) { 327 327 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, 328 328 ISCSI_LOGIN_STATUS_NO_RESOURCES);
+1 -1
drivers/target/loopback/tcm_loop.c
··· 1018 1018 /* 1019 1019 * Initialize the struct se_session pointer 1020 1020 */ 1021 - tl_nexus->se_sess = transport_init_session(); 1021 + tl_nexus->se_sess = transport_init_session(TARGET_PROT_ALL); 1022 1022 if (IS_ERR(tl_nexus->se_sess)) { 1023 1023 ret = PTR_ERR(tl_nexus->se_sess); 1024 1024 goto out;
+1 -1
drivers/target/sbp/sbp_target.c
··· 210 210 return ERR_PTR(-ENOMEM); 211 211 } 212 212 213 - sess->se_sess = transport_init_session(); 213 + sess->se_sess = transport_init_session(TARGET_PROT_NORMAL); 214 214 if (IS_ERR(sess->se_sess)) { 215 215 pr_err("failed to init se_session\n"); 216 216
+5 -3
drivers/target/target_core_transport.c
··· 235 235 sub_api_initialized = 1; 236 236 } 237 237 238 - struct se_session *transport_init_session(void) 238 + struct se_session *transport_init_session(enum target_prot_op sup_prot_ops) 239 239 { 240 240 struct se_session *se_sess; 241 241 ··· 251 251 INIT_LIST_HEAD(&se_sess->sess_wait_list); 252 252 spin_lock_init(&se_sess->sess_cmd_lock); 253 253 kref_init(&se_sess->sess_kref); 254 + se_sess->sup_prot_ops = sup_prot_ops; 254 255 255 256 return se_sess; 256 257 } ··· 289 288 EXPORT_SYMBOL(transport_alloc_session_tags); 290 289 291 290 struct se_session *transport_init_session_tags(unsigned int tag_num, 292 - unsigned int tag_size) 291 + unsigned int tag_size, 292 + enum target_prot_op sup_prot_ops) 293 293 { 294 294 struct se_session *se_sess; 295 295 int rc; 296 296 297 - se_sess = transport_init_session(); 297 + se_sess = transport_init_session(sup_prot_ops); 298 298 if (IS_ERR(se_sess)) 299 299 return se_sess; 300 300
+2 -1
drivers/target/tcm_fc/tfc_sess.c
··· 211 211 return NULL; 212 212 213 213 sess->se_sess = transport_init_session_tags(TCM_FC_DEFAULT_TAGS, 214 - sizeof(struct ft_cmd)); 214 + sizeof(struct ft_cmd), 215 + TARGET_PROT_NORMAL); 215 216 if (IS_ERR(sess->se_sess)) { 216 217 kfree(sess); 217 218 return NULL;
+1 -1
drivers/usb/gadget/tcm_usb_gadget.c
··· 1731 1731 pr_err("Unable to allocate struct tcm_vhost_nexus\n"); 1732 1732 goto err_unlock; 1733 1733 } 1734 - tv_nexus->tvn_se_sess = transport_init_session(); 1734 + tv_nexus->tvn_se_sess = transport_init_session(TARGET_PROT_NORMAL); 1735 1735 if (IS_ERR(tv_nexus->tvn_se_sess)) 1736 1736 goto err_free; 1737 1737
+2 -1
drivers/vhost/scsi.c
··· 1745 1745 */ 1746 1746 tv_nexus->tvn_se_sess = transport_init_session_tags( 1747 1747 TCM_VHOST_DEFAULT_TAGS, 1748 - sizeof(struct tcm_vhost_cmd)); 1748 + sizeof(struct tcm_vhost_cmd), 1749 + TARGET_PROT_NORMAL); 1749 1750 if (IS_ERR(tv_nexus->tvn_se_sess)) { 1750 1751 mutex_unlock(&tpg->tv_tpg_mutex); 1751 1752 kfree(tv_nexus);
+1
include/target/iscsi/iscsi_transport.h
··· 22 22 int (*iscsit_queue_data_in)(struct iscsi_conn *, struct iscsi_cmd *); 23 23 int (*iscsit_queue_status)(struct iscsi_conn *, struct iscsi_cmd *); 24 24 void (*iscsit_aborted_task)(struct iscsi_conn *, struct iscsi_cmd *); 25 + enum target_prot_op (*iscsit_get_sup_prot_ops)(struct iscsi_conn *); 25 26 }; 26 27 27 28 static inline void *iscsit_priv_cmd(struct iscsi_cmd *cmd)
+12 -7
include/target/target_core_base.h
··· 442 442 }; 443 443 444 444 enum target_prot_op { 445 - TARGET_PROT_NORMAL = 0, 446 - TARGET_PROT_DIN_INSERT, 447 - TARGET_PROT_DOUT_INSERT, 448 - TARGET_PROT_DIN_STRIP, 449 - TARGET_PROT_DOUT_STRIP, 450 - TARGET_PROT_DIN_PASS, 451 - TARGET_PROT_DOUT_PASS, 445 + TARGET_PROT_NORMAL = 0, 446 + TARGET_PROT_DIN_INSERT = (1 << 0), 447 + TARGET_PROT_DOUT_INSERT = (1 << 1), 448 + TARGET_PROT_DIN_STRIP = (1 << 2), 449 + TARGET_PROT_DOUT_STRIP = (1 << 3), 450 + TARGET_PROT_DIN_PASS = (1 << 4), 451 + TARGET_PROT_DOUT_PASS = (1 << 5), 452 452 }; 453 + 454 + #define TARGET_PROT_ALL TARGET_PROT_DIN_INSERT | TARGET_PROT_DOUT_INSERT | \ 455 + TARGET_PROT_DIN_STRIP | TARGET_PROT_DOUT_STRIP | \ 456 + TARGET_PROT_DIN_PASS | TARGET_PROT_DOUT_PASS 453 457 454 458 enum target_prot_type { 455 459 TARGET_DIF_TYPE0_PROT, ··· 609 605 struct se_session { 610 606 unsigned sess_tearing_down:1; 611 607 u64 sess_bin_isid; 608 + enum target_prot_op sup_prot_ops; 612 609 struct se_node_acl *se_node_acl; 613 610 struct se_portal_group *se_tpg; 614 611 void *fabric_sess_ptr;
+3 -2
include/target/target_core_fabric.h
··· 84 84 void (*fabric_drop_nodeacl)(struct se_node_acl *); 85 85 }; 86 86 87 - struct se_session *transport_init_session(void); 87 + struct se_session *transport_init_session(enum target_prot_op); 88 88 int transport_alloc_session_tags(struct se_session *, unsigned int, 89 89 unsigned int); 90 - struct se_session *transport_init_session_tags(unsigned int, unsigned int); 90 + struct se_session *transport_init_session_tags(unsigned int, unsigned int, 91 + enum target_prot_op); 91 92 void __transport_register_session(struct se_portal_group *, 92 93 struct se_node_acl *, struct se_session *, void *); 93 94 void transport_register_session(struct se_portal_group *,