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

Configure Feed

Select the types of activity you want to include in your feed.

Merge git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending

Pull SCSI target fixes from Nicholas Bellinger:
"Here are the outstanding target fixes queued up for v3.12-rc4 code.

The highlights include:

- Make vhost/scsi tag percpu_ida_alloc() use GFP_ATOMIC
- Allow sess_cmd_map allocation failure fallback to use vzalloc
- Fix COMPARE_AND_WRITE se_cmd->data_length bug with FILEIO backends
- Fixes for COMPARE_AND_WRITE callback recursive failure OOPs + non
zero scsi_status bug
- Make iscsi-target do acknowledgement tag release from RX context
- Setup iscsi-target with extra (cmdsn_depth / 2) percpu_ida tags

Also included is a iscsi-target patch CC'ed for v3.10+ that avoids
legacy wait_for_task=true release during fast-past StatSN
acknowledgement, and two other SRP target related patches that address
long-standing issues that are CC'ed for v3.3+.

Extra thanks to Thomas Glanzmann for his testing feedback with
COMPARE_AND_WRITE + EXTENDED_COPY VAAI logic"

* git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending:
iscsi-target; Allow an extra tag_num / 2 number of percpu_ida tags
iscsi-target: Perform release of acknowledged tags from RX context
iscsi-target: Only perform wait_for_tasks when performing shutdown
target: Fail on non zero scsi_status in compare_and_write_callback
target: Fix recursive COMPARE_AND_WRITE callback failure
target: Reset data_length for COMPARE_AND_WRITE to NoLB * block_size
ib_srpt: always set response for task management
target: Fall back to vzalloc upon ->sess_cmd_map kzalloc failure
vhost/scsi: Use GFP_ATOMIC with percpu_ida_alloc for obtaining tag
ib_srpt: Destroy cm_id before destroying QP.
target: Fix xop->dbl assignment in target_xcopy_parse_segdesc_02

+67 -25
+6 -8
drivers/infiniband/ulp/srpt/ib_srpt.c
··· 1588 1588 int resp_data_len; 1589 1589 int resp_len; 1590 1590 1591 - resp_data_len = (rsp_code == SRP_TSK_MGMT_SUCCESS) ? 0 : 4; 1591 + resp_data_len = 4; 1592 1592 resp_len = sizeof(*srp_rsp) + resp_data_len; 1593 1593 1594 1594 srp_rsp = ioctx->ioctx.buf; ··· 1600 1600 + atomic_xchg(&ch->req_lim_delta, 0)); 1601 1601 srp_rsp->tag = tag; 1602 1602 1603 - if (rsp_code != SRP_TSK_MGMT_SUCCESS) { 1604 - srp_rsp->flags |= SRP_RSP_FLAG_RSPVALID; 1605 - srp_rsp->resp_data_len = cpu_to_be32(resp_data_len); 1606 - srp_rsp->data[3] = rsp_code; 1607 - } 1603 + srp_rsp->flags |= SRP_RSP_FLAG_RSPVALID; 1604 + srp_rsp->resp_data_len = cpu_to_be32(resp_data_len); 1605 + srp_rsp->data[3] = rsp_code; 1608 1606 1609 1607 return resp_len; 1610 1608 } ··· 2356 2358 transport_deregister_session(se_sess); 2357 2359 ch->sess = NULL; 2358 2360 2361 + ib_destroy_cm_id(ch->cm_id); 2362 + 2359 2363 srpt_destroy_ch_ib(ch); 2360 2364 2361 2365 srpt_free_ioctx_ring((struct srpt_ioctx **)ch->ioctx_ring, ··· 2367 2367 spin_lock_irq(&sdev->spinlock); 2368 2368 list_del(&ch->list); 2369 2369 spin_unlock_irq(&sdev->spinlock); 2370 - 2371 - ib_destroy_cm_id(ch->cm_id); 2372 2370 2373 2371 if (ch->release_done) 2374 2372 complete(ch->release_done);
+9 -4
drivers/target/iscsi/iscsi_target.c
··· 753 753 754 754 static void iscsit_ack_from_expstatsn(struct iscsi_conn *conn, u32 exp_statsn) 755 755 { 756 - struct iscsi_cmd *cmd; 756 + LIST_HEAD(ack_list); 757 + struct iscsi_cmd *cmd, *cmd_p; 757 758 758 759 conn->exp_statsn = exp_statsn; 759 760 ··· 762 761 return; 763 762 764 763 spin_lock_bh(&conn->cmd_lock); 765 - list_for_each_entry(cmd, &conn->conn_cmd_list, i_conn_node) { 764 + list_for_each_entry_safe(cmd, cmd_p, &conn->conn_cmd_list, i_conn_node) { 766 765 spin_lock(&cmd->istate_lock); 767 766 if ((cmd->i_state == ISTATE_SENT_STATUS) && 768 767 iscsi_sna_lt(cmd->stat_sn, exp_statsn)) { 769 768 cmd->i_state = ISTATE_REMOVE; 770 769 spin_unlock(&cmd->istate_lock); 771 - iscsit_add_cmd_to_immediate_queue(cmd, conn, 772 - cmd->i_state); 770 + list_move_tail(&cmd->i_conn_node, &ack_list); 773 771 continue; 774 772 } 775 773 spin_unlock(&cmd->istate_lock); 776 774 } 777 775 spin_unlock_bh(&conn->cmd_lock); 776 + 777 + list_for_each_entry_safe(cmd, cmd_p, &ack_list, i_conn_node) { 778 + list_del(&cmd->i_conn_node); 779 + iscsit_free_cmd(cmd, false); 780 + } 778 781 } 779 782 780 783 static int iscsit_allocate_iovecs(struct iscsi_cmd *cmd)
+1 -1
drivers/target/iscsi/iscsi_target_nego.c
··· 1192 1192 */ 1193 1193 alloc_tags: 1194 1194 tag_num = max_t(u32, ISCSIT_MIN_TAGS, queue_depth); 1195 - tag_num += ISCSIT_EXTRA_TAGS; 1195 + tag_num += (tag_num / 2) + ISCSIT_EXTRA_TAGS; 1196 1196 tag_size = sizeof(struct iscsi_cmd) + conn->conn_transport->priv_size; 1197 1197 1198 1198 ret = transport_alloc_session_tags(sess->se_sess, tag_num, tag_size);
+2 -2
drivers/target/iscsi/iscsi_target_util.c
··· 736 736 * Fallthrough 737 737 */ 738 738 case ISCSI_OP_SCSI_TMFUNC: 739 - rc = transport_generic_free_cmd(&cmd->se_cmd, 1); 739 + rc = transport_generic_free_cmd(&cmd->se_cmd, shutdown); 740 740 if (!rc && shutdown && se_cmd && se_cmd->se_sess) { 741 741 __iscsit_free_cmd(cmd, true, shutdown); 742 742 target_put_sess_cmd(se_cmd->se_sess, se_cmd); ··· 752 752 se_cmd = &cmd->se_cmd; 753 753 __iscsit_free_cmd(cmd, true, shutdown); 754 754 755 - rc = transport_generic_free_cmd(&cmd->se_cmd, 1); 755 + rc = transport_generic_free_cmd(&cmd->se_cmd, shutdown); 756 756 if (!rc && shutdown && se_cmd->se_sess) { 757 757 __iscsit_free_cmd(cmd, true, shutdown); 758 758 target_put_sess_cmd(se_cmd->se_sess, se_cmd);
+26 -2
drivers/target/target_core_sbc.c
··· 349 349 { 350 350 struct se_device *dev = cmd->se_dev; 351 351 352 - cmd->se_cmd_flags |= SCF_COMPARE_AND_WRITE_POST; 352 + /* 353 + * Only set SCF_COMPARE_AND_WRITE_POST to force a response fall-through 354 + * within target_complete_ok_work() if the command was successfully 355 + * sent to the backend driver. 356 + */ 357 + spin_lock_irq(&cmd->t_state_lock); 358 + if ((cmd->transport_state & CMD_T_SENT) && !cmd->scsi_status) 359 + cmd->se_cmd_flags |= SCF_COMPARE_AND_WRITE_POST; 360 + spin_unlock_irq(&cmd->t_state_lock); 361 + 353 362 /* 354 363 * Unlock ->caw_sem originally obtained during sbc_compare_and_write() 355 364 * before the original READ I/O submission. ··· 372 363 { 373 364 struct se_device *dev = cmd->se_dev; 374 365 struct scatterlist *write_sg = NULL, *sg; 375 - unsigned char *buf, *addr; 366 + unsigned char *buf = NULL, *addr; 376 367 struct sg_mapping_iter m; 377 368 unsigned int offset = 0, len; 378 369 unsigned int nlbas = cmd->t_task_nolb; ··· 387 378 */ 388 379 if (!cmd->t_data_sg || !cmd->t_bidi_data_sg) 389 380 return TCM_NO_SENSE; 381 + /* 382 + * Immediately exit + release dev->caw_sem if command has already 383 + * been failed with a non-zero SCSI status. 384 + */ 385 + if (cmd->scsi_status) { 386 + pr_err("compare_and_write_callback: non zero scsi_status:" 387 + " 0x%02x\n", cmd->scsi_status); 388 + goto out; 389 + } 390 390 391 391 buf = kzalloc(cmd->data_length, GFP_KERNEL); 392 392 if (!buf) { ··· 526 508 cmd->transport_complete_callback = NULL; 527 509 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 528 510 } 511 + /* 512 + * Reset cmd->data_length to individual block_size in order to not 513 + * confuse backend drivers that depend on this value matching the 514 + * size of the I/O being submitted. 515 + */ 516 + cmd->data_length = cmd->t_task_nolb * dev->dev_attrib.block_size; 529 517 530 518 ret = cmd->execute_rw(cmd, cmd->t_bidi_data_sg, cmd->t_bidi_data_nents, 531 519 DMA_FROM_DEVICE);
+15 -5
drivers/target/target_core_transport.c
··· 236 236 { 237 237 int rc; 238 238 239 - se_sess->sess_cmd_map = kzalloc(tag_num * tag_size, GFP_KERNEL); 239 + se_sess->sess_cmd_map = kzalloc(tag_num * tag_size, 240 + GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT); 240 241 if (!se_sess->sess_cmd_map) { 241 - pr_err("Unable to allocate se_sess->sess_cmd_map\n"); 242 - return -ENOMEM; 242 + se_sess->sess_cmd_map = vzalloc(tag_num * tag_size); 243 + if (!se_sess->sess_cmd_map) { 244 + pr_err("Unable to allocate se_sess->sess_cmd_map\n"); 245 + return -ENOMEM; 246 + } 243 247 } 244 248 245 249 rc = percpu_ida_init(&se_sess->sess_tag_pool, tag_num); 246 250 if (rc < 0) { 247 251 pr_err("Unable to init se_sess->sess_tag_pool," 248 252 " tag_num: %u\n", tag_num); 249 - kfree(se_sess->sess_cmd_map); 253 + if (is_vmalloc_addr(se_sess->sess_cmd_map)) 254 + vfree(se_sess->sess_cmd_map); 255 + else 256 + kfree(se_sess->sess_cmd_map); 250 257 se_sess->sess_cmd_map = NULL; 251 258 return -ENOMEM; 252 259 } ··· 419 412 { 420 413 if (se_sess->sess_cmd_map) { 421 414 percpu_ida_destroy(&se_sess->sess_tag_pool); 422 - kfree(se_sess->sess_cmd_map); 415 + if (is_vmalloc_addr(se_sess->sess_cmd_map)) 416 + vfree(se_sess->sess_cmd_map); 417 + else 418 + kfree(se_sess->sess_cmd_map); 423 419 } 424 420 kmem_cache_free(se_sess_cache, se_sess); 425 421 }
+2 -2
drivers/target/target_core_xcopy.c
··· 298 298 (unsigned long long)xop->dst_lba); 299 299 300 300 if (dc != 0) { 301 - xop->dbl = (desc[29] << 16) & 0xff; 302 - xop->dbl |= (desc[30] << 8) & 0xff; 301 + xop->dbl = (desc[29] & 0xff) << 16; 302 + xop->dbl |= (desc[30] & 0xff) << 8; 303 303 xop->dbl |= desc[31] & 0xff; 304 304 305 305 pr_debug("XCOPY seg desc 0x02: DC=1 w/ dbl: %u\n", xop->dbl);
+6 -1
drivers/vhost/scsi.c
··· 728 728 } 729 729 se_sess = tv_nexus->tvn_se_sess; 730 730 731 - tag = percpu_ida_alloc(&se_sess->sess_tag_pool, GFP_KERNEL); 731 + tag = percpu_ida_alloc(&se_sess->sess_tag_pool, GFP_ATOMIC); 732 + if (tag < 0) { 733 + pr_err("Unable to obtain tag for tcm_vhost_cmd\n"); 734 + return ERR_PTR(-ENOMEM); 735 + } 736 + 732 737 cmd = &((struct tcm_vhost_cmd *)se_sess->sess_cmd_map)[tag]; 733 738 sg = cmd->tvc_sgl; 734 739 pages = cmd->tvc_upages;