From 0a7c9e1f678b533d2371b36010eb38edde3cdedf Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Fri, 18 Sep 2009 18:58:55 +0000 Subject: [PATCH] Potential fix for the following kernel bug report: ------------[ cut here ]------------ ib_srpt: srpt_xmit_response: tag= 26 channel in bad state 2 scst: ***ERROR***: Target driver ib_srpt xmit_response() returned fatal error ib_srpt: srpt_xmit_response: tag= 38 channel in bad state 2 scst: ***ERROR***: Target driver ib_srpt xmit_response() returned fatal error ib_srpt: srpt_xmit_response: tag= 27 channel in bad state 2 kernel BUG at /root/scst/scst/src/scst_targ.c:3089! invalid opcode: 0000 [1] SMP CPU 0 ... RIP: 0010:[] [] scst_tgt_cmd_done+0x26/0x30 [scst] RSP: 0018:ffff88039ad27b50 EFLAGS: 00010297 RAX: 0000000000000200 RBX: ffff8803ad9c68f8 RCX: 0000000000000000 RDX: 00000000ffffffff RSI: 0000000000000000 RDI: ffff8803ad9c68f8 RBP: ffff88039ad27b50 R08: 0000000000000000 R09: 0000000000000000 R10: ffff88039ad277c0 R11: ffff88041ad278cf R12: ffff8803c2972180 R13: ffff88039ada0000 R14: 0000000000000001 R15: ffff8803fb00c2b0 FS: 0000000000000000(0000) GS:ffffffff807dd000(0000) knlGS:0000000000000000 CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b CR2: 00007f9281e64000 CR3: 0000000000201000 CR4: 00000000000006e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process ib_cm/0 (pid: 8299, threadinfo ffff88039ad26000, task ffff88039ad40000) Stack: ffff88039ad27b80 ffffffffa04c0c47 ffff88039a8db900 ffff8803c2972180 ffff8803fb00c240 ffff8803fb00c284 ffff88039ad27bc0 ffffffffa04c0d93 ffff88042a4959c0 ffff88042a9d7800 ffff88042544da00 ffff88042a9d7898 Call Trace: [] srpt_abort_scst_cmd+0xd7/0x160 [ib_srpt] [] srpt_release_channel+0xc3/0x190 [ib_srpt] [] srpt_find_and_release_channel+0x22/0x30 [ib_srpt] [] srpt_cm_handler+0x6d/0xbb8 [ib_srpt] [] ? try_to_wake_up+0x126/0x2f0 [] ? default_wake_function+0xd/0x10 [] ? autoremove_wake_function+0x16/0x40 [] ? __wake_up_common+0x5a/0x90 [] ? __wake_up+0x4e/0x70 [] ? __queue_work+0x41/0x50 [] ? queue_work_on+0x4d/0x60 [] ? queue_work+0x1f/0x30 [] ? queue_delayed_work+0x2d/0x40 [] ? wait_for_response+0xd5/0xe0 [ib_mad] [] cm_process_work+0x27/0x130 [ib_cm] [] cm_drep_handler+0xf1/0x180 [ib_cm] [] ? cm_work_handler+0x0/0x1b8 [ib_cm] [] cm_work_handler+0x105/0x1b8 [ib_cm] [] ? cm_work_handler+0x0/0x1b8 [ib_cm] [] run_workqueue+0xc2/0x1a0 [] worker_thread+0xaf/0x130 [] ? autoremove_wake_function+0x0/0x40 [] ? worker_thread+0x0/0x130 [] kthread+0x4e/0x90 [] child_rip+0xa/0x11 [] ? kthread+0x0/0x90 [] ? child_rip+0x0/0x11 Code: 00 00 00 00 00 55 48 89 e5 e8 a7 cc d9 df 83 7f 28 78 75 17 80 67 2d f7 c7 47 28 0d 00 00 00 ba 01 00 00 00 e8 8c fc ff ff c9 c3 <0f> 0b eb fe 66 0f 1f 44 00 00 55 48 89 e5 41 54 53 e8 74 cc d9 RIP [] scst_tgt_cmd_done+0x26/0x30 [scst] RSP ---[ end trace a7f20725e9471e16 ]--- git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@1115 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- srpt/src/ib_srpt.c | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/srpt/src/ib_srpt.c b/srpt/src/ib_srpt.c index f20c4673d..4be705758 100644 --- a/srpt/src/ib_srpt.c +++ b/srpt/src/ib_srpt.c @@ -904,25 +904,26 @@ static void srpt_abort_scst_cmd(struct srpt_device *sdev, ioctx->state == SRPT_STATE_PROCESSED); } #endif - - orig_ioctx_state = ioctx->state; - ioctx->state = SRPT_STATE_ABORTED; - - if (orig_ioctx_state == SRPT_STATE_NEED_DATA) { - WARN_ON(scst_cmd_get_data_direction(ioctx->scmnd) - == SCST_DATA_READ); - scst_rx_data(scmnd, - tell_initiator ? SCST_RX_STATUS_ERROR - : SCST_RX_STATUS_ERROR_FATAL, - SCST_CONTEXT_THREAD); - goto out; - } else if (ioctx->state == SRPT_STATE_PROCESSED) - ; - else - WARN_ON("unexpected cmd state"); } + orig_ioctx_state = ioctx->state; + ioctx->state = SRPT_STATE_ABORTED; + + if (orig_ioctx_state == SRPT_STATE_NEED_DATA) { + WARN_ON(scst_cmd_get_data_direction(ioctx->scmnd) + == SCST_DATA_READ); + scst_rx_data(scmnd, + tell_initiator ? SCST_RX_STATUS_ERROR + : SCST_RX_STATUS_ERROR_FATAL, + SCST_CONTEXT_THREAD); + goto out; + } else if (ioctx->state == SRPT_STATE_PROCESSED) + ; + else + WARN_ON("unexpected cmd state"); + scst_set_delivery_status(scmnd, SCST_CMD_DELIVERY_FAILED); + WARN_ON(scmnd->state != SCST_CMD_STATE_XMIT_WAIT); scst_tgt_cmd_done(scmnd, scst_estimate_context()); out: return; @@ -960,6 +961,7 @@ static void srpt_handle_send_comp(struct srpt_rdma_ch *ch, scst_cmd_get_sg_cnt(ioctx->scmnd), scst_to_tgt_dma_dir(dir)); + WARN_ON(ioctx->scmnd->state != SCST_CMD_STATE_XMIT_WAIT); scst_tgt_cmd_done(ioctx->scmnd, context); } else srpt_reset_ioctx(ch, ioctx); @@ -2397,6 +2399,7 @@ out_aborted: ret = SCST_TGT_RES_SUCCESS; scst_set_delivery_status(scmnd, SCST_CMD_DELIVERY_ABORTED); ioctx->state = SRPT_STATE_ABORTED; + WARN_ON(scmnd->state != SCST_CMD_STATE_XMIT_WAIT); scst_tgt_cmd_done(scmnd, SCST_CONTEXT_SAME); goto out; }