scsi: be2iscsi: Fix async PDU handling path
BUG: unable to handle kernel NULL pointer dereference at
000000000000015e
IP: [<
ffffffffa0081700>]
hwi_get_async_handle.isra.23.constprop.39+0x90/0x1d0 [be2iscsi]
PGD 0
Oops: 0000 [#1] SMP
...
Call Trace:
<IRQ>
[<
ffffffffa00818bc>] hwi_process_default_pdu_ring+0x7c/0x280 [be2iscsi]
[<
ffffffffa0088f51>] beiscsi_process_cq+0x321/0xb90 [be2iscsi]
[<
ffffffff810af028>] ? __wake_up_common+0x58/0x90
[<
ffffffff810b0d84>] ? __wake_up+0x44/0x50
[<
ffffffffa0089a2d>] be_iopoll+0x1d/0xb0 [be2iscsi]
[<
ffffffff812d1f61>] blk_iopoll_softirq+0xc1/0x100
[<
ffffffff81084b0f>] __do_softirq+0xef/0x280
The symptom observed is multiple async handles get queued for same index
thus causing leak in buffers posted to FW.
The root cause is:
- async handle is continued to be used even if it does not match the
completion.
- list_move operation done on already filled index.
1. Remove use of writables, host_write_ptr and ep_read_ptr.
2. Remove consumed logic to update writables. Instead, use only
free_entries to do the accounting of handles to be posted back.
3. Remove busy_list, instead use simple slot to index handles.
4. Added check no data, header less and overflow to make sure
all async_handles are flushed in error cases.
5. Added code to verify gathering of handles to form PDU by
checking final bit before forwarding PDU.
6. Added code to catch mismatch with CQE and handle gracefully.
7. Use AMAP, traverse cri_wait_queue list to post buffers, log
"async PDU" related errors.
8. Rearranged few data structures and added comments in init &
processing path.
9. Added WARN_ONs to catch any HD ring corruption.
Signed-off-by: Jitendra Bhivare <jitendra.bhivare@broadcom.com>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>