Re: [PATCH V4 3/4] Introduce XEN scsiback module

2014-08-16 Thread Nicholas A. Bellinger
On Wed, 2014-08-13 at 09:02 +0200, Juergen Gross wrote:
 On 08/12/2014 11:13 PM, Nicholas A. Bellinger wrote:

SNIP

 
  +
  +static int scsiback_port_link(struct se_portal_group *se_tpg,
  + struct se_lun *lun)
  +{
  +  struct scsiback_tpg *tpg = container_of(se_tpg,
  +  struct scsiback_tpg, se_tpg);
  +
  +  mutex_lock(scsiback_mutex);
  +
  +  mutex_lock(tpg-tv_tpg_mutex);
  +  tpg-tv_tpg_port_count++;
  +  mutex_unlock(tpg-tv_tpg_mutex);
  +
  +  mutex_unlock(scsiback_mutex);
  +
  +  return 0;
  +}
  +
 
  AFAICT, no need to hold scsiback_mutex while incrementing
  tpg-tv_tpg_port_count.
 
 So there is a guarantee that port_link and port_unlink are never
 called in parallel?
 

Correct.  configfs_symlink() only calls create_link() once
type-ct_item_ops-allow_link() - target_fabric_port_link() -
TFO-fabric_post_link() has successfully completed, effectively
preventing configfs_unlink() + subsequent TFO-fabric_pre_unlink()
execution until after configfs_symlink() completes.

--nab

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH V4 3/4] Introduce XEN scsiback module

2014-08-13 Thread Juergen Gross

On 08/12/2014 11:13 PM, Nicholas A. Bellinger wrote:

Hi Juergen  Co,

Finally had a chance to review this code.  Comments are inline below..


Thank you very much for your review!



On Fri, 2014-08-08 at 09:49 +0200, jgr...@suse.com wrote:

From: Juergen Gross jgr...@suse.com

Introduces the XEN pvSCSI backend. With pvSCSI it is possible for a XEN domU
to issue SCSI commands to a SCSI LUN assigned to that domU. The SCSI commands
are passed to the pvSCSI backend in a driver domain (usually Dom0) which is
owner of the physical device. This allows e.g. to use SCSI tape drives in a
XEN domU.

The code is taken from the pvSCSI implementation in XEN done by Fujitsu based
on Linux kernel 2.6.18.

Changes from the original version are:
- port to upstream kernel
- put all code in just one source file
- adapt to Linux style guide
- use target core infrastructure instead doing pure pass-through
- enable module unloading
- support SG-list in grant page(s)
- support task abort
- remove redundant struct backend
- allocate resources dynamically
- correct minor error in scsiback_fast_flush_area
- free allocated resources in case of error during I/O preparation
- remove CDB emulation, now handled by target core infrastructure

Signed-off-by: Juergen Gross jgr...@suse.com

Xen related parts
Acked-by: David Vrabel david.vra...@citrix.com
---


SNIP


diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c
new file mode 100644
index 000..4a0d6e3
--- /dev/null
+++ b/drivers/xen/xen-scsiback.c


SNIP


+struct scsiback_nacl {
+   /* Binary World Wide unique Port Name for pvscsi Initiator port */
+   u64 iport_wwpn;
+   /* ASCII formatted WWPN for Sas Initiator port */
+   char iport_name[VSCSI_NAMELEN];
+   /* Returned by scsiback_make_nodeacl() */
+   struct se_node_acl se_node_acl;
+};
+


Given that this code is similar to how loopback + vhost-scsi function,
and uses a (locally) generated nexus for each WWPN endpoint, the
scsiback_nacl and associated code will be unused should be be dropped.


Done.



SNIP


+static void scsiback_do_resp_with_sense(char *sense_buffer, int32_t result,
+   uint32_t resid, struct vscsibk_pend *pending_req)
+{
+   struct vscsiif_response *ring_res;
+   struct vscsibk_info *info = pending_req-info;
+   int notify;
+   struct scsi_sense_hdr sshdr;
+   unsigned long flags;
+   unsigned len;
+
+   spin_lock_irqsave(info-ring_lock, flags);
+
+   ring_res = RING_GET_RESPONSE(info-ring, info-ring.rsp_prod_pvt);
+   info-ring.rsp_prod_pvt++;
+
+   ring_res-rslt   = result;
+   ring_res-rqid   = pending_req-rqid;
+
+   if (sense_buffer != NULL 
+   scsi_normalize_sense(sense_buffer, VSCSIIF_SENSE_BUFFERSIZE,
+sshdr)) {
+   len = min_t(unsigned, 8 + sense_buffer[7],
+   VSCSIIF_SENSE_BUFFERSIZE);
+   memcpy(ring_res-sense_buffer, sense_buffer, len);
+   ring_res-sense_len = len;
+   } else {
+   ring_res-sense_len = 0;
+   }
+
+   ring_res-residual_len = resid;
+
+   RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(info-ring, notify);
+   spin_unlock_irqrestore(info-ring_lock, flags);
+
+   if (notify)
+   notify_remote_via_irq(info-irq);
+
+   if (pending_req-v2p)
+   kref_put(pending_req-v2p-kref,
+scsiback_free_translation_entry);
+
+   kmem_cache_free(scsiback_cachep, pending_req);
+}
+
+static void scsiback_cmd_done(struct vscsibk_pend *pending_req)
+{
+   struct vscsibk_info *info = pending_req-info;
+   unsigned char *sense_buffer;
+   unsigned int resid;
+   int errors;
+
+   sense_buffer = pending_req-sense_buffer;
+   resid= pending_req-se_cmd.residual_count;
+   errors   = pending_req-result;
+
+   if (errors  log_print_stat)
+   scsiback_print_status(sense_buffer, errors, pending_req);
+
+   scsiback_fast_flush_area(pending_req);
+   scsiback_do_resp_with_sense(sense_buffer, errors, resid, pending_req);
+   scsiback_put(info);
+
+   transport_generic_free_cmd(pending_req-se_cmd, 0);
+}
+


The usage here of scsiback_do_resp_with_sense() - kmem_cache_free() for
*pending_req, and then invoking transport_generic_free_cmd() with
pending_req-se_cmd is an free after use bug..

So the way this should work is similar to how loopback currently does
things:

   - Move the kmem_cache_free() for pending_req from
 scsiback_do_resp_with_sense() to scsiback_release_cmd()
   - Remove the transport_generic_free_cmd() from scsiback_cmd_done()
   - Copy what tcm_loop_check_stop_free() does into
 scsiback_check_stop_free(), and remove target_put_sess_cmd()


Done.




+static void scsiback_cmd_exec(struct vscsibk_pend *pending_req)
+{
+   struct se_cmd *se_cmd = pending_req-se_cmd;
+   struct se_session *sess = 

Re: [PATCH V4 3/4] Introduce XEN scsiback module

2014-08-12 Thread Nicholas A. Bellinger
Hi Juergen  Co,

Finally had a chance to review this code.  Comments are inline below..

On Fri, 2014-08-08 at 09:49 +0200, jgr...@suse.com wrote:
 From: Juergen Gross jgr...@suse.com
 
 Introduces the XEN pvSCSI backend. With pvSCSI it is possible for a XEN domU
 to issue SCSI commands to a SCSI LUN assigned to that domU. The SCSI commands
 are passed to the pvSCSI backend in a driver domain (usually Dom0) which is
 owner of the physical device. This allows e.g. to use SCSI tape drives in a
 XEN domU.
 
 The code is taken from the pvSCSI implementation in XEN done by Fujitsu based
 on Linux kernel 2.6.18.
 
 Changes from the original version are:
 - port to upstream kernel
 - put all code in just one source file
 - adapt to Linux style guide
 - use target core infrastructure instead doing pure pass-through
 - enable module unloading
 - support SG-list in grant page(s)
 - support task abort
 - remove redundant struct backend
 - allocate resources dynamically
 - correct minor error in scsiback_fast_flush_area
 - free allocated resources in case of error during I/O preparation
 - remove CDB emulation, now handled by target core infrastructure
 
 Signed-off-by: Juergen Gross jgr...@suse.com
 
 Xen related parts
 Acked-by: David Vrabel david.vra...@citrix.com
 ---

SNIP

 diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c
 new file mode 100644
 index 000..4a0d6e3
 --- /dev/null
 +++ b/drivers/xen/xen-scsiback.c

SNIP

 +struct scsiback_nacl {
 + /* Binary World Wide unique Port Name for pvscsi Initiator port */
 + u64 iport_wwpn;
 + /* ASCII formatted WWPN for Sas Initiator port */
 + char iport_name[VSCSI_NAMELEN];
 + /* Returned by scsiback_make_nodeacl() */
 + struct se_node_acl se_node_acl;
 +};
 +

Given that this code is similar to how loopback + vhost-scsi function,
and uses a (locally) generated nexus for each WWPN endpoint, the
scsiback_nacl and associated code will be unused should be be dropped.

SNIP

 +static void scsiback_do_resp_with_sense(char *sense_buffer, int32_t result,
 + uint32_t resid, struct vscsibk_pend *pending_req)
 +{
 + struct vscsiif_response *ring_res;
 + struct vscsibk_info *info = pending_req-info;
 + int notify;
 + struct scsi_sense_hdr sshdr;
 + unsigned long flags;
 + unsigned len;
 +
 + spin_lock_irqsave(info-ring_lock, flags);
 +
 + ring_res = RING_GET_RESPONSE(info-ring, info-ring.rsp_prod_pvt);
 + info-ring.rsp_prod_pvt++;
 +
 + ring_res-rslt   = result;
 + ring_res-rqid   = pending_req-rqid;
 +
 + if (sense_buffer != NULL 
 + scsi_normalize_sense(sense_buffer, VSCSIIF_SENSE_BUFFERSIZE,
 +  sshdr)) {
 + len = min_t(unsigned, 8 + sense_buffer[7],
 + VSCSIIF_SENSE_BUFFERSIZE);
 + memcpy(ring_res-sense_buffer, sense_buffer, len);
 + ring_res-sense_len = len;
 + } else {
 + ring_res-sense_len = 0;
 + }
 +
 + ring_res-residual_len = resid;
 +
 + RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(info-ring, notify);
 + spin_unlock_irqrestore(info-ring_lock, flags);
 +
 + if (notify)
 + notify_remote_via_irq(info-irq);
 +
 + if (pending_req-v2p)
 + kref_put(pending_req-v2p-kref,
 +  scsiback_free_translation_entry);
 +
 + kmem_cache_free(scsiback_cachep, pending_req);
 +}
 +
 +static void scsiback_cmd_done(struct vscsibk_pend *pending_req)
 +{
 + struct vscsibk_info *info = pending_req-info;
 + unsigned char *sense_buffer;
 + unsigned int resid;
 + int errors;
 +
 + sense_buffer = pending_req-sense_buffer;
 + resid= pending_req-se_cmd.residual_count;
 + errors   = pending_req-result;
 +
 + if (errors  log_print_stat)
 + scsiback_print_status(sense_buffer, errors, pending_req);
 +
 + scsiback_fast_flush_area(pending_req);
 + scsiback_do_resp_with_sense(sense_buffer, errors, resid, pending_req);
 + scsiback_put(info);
 +
 + transport_generic_free_cmd(pending_req-se_cmd, 0);
 +}
 +

The usage here of scsiback_do_resp_with_sense() - kmem_cache_free() for
*pending_req, and then invoking transport_generic_free_cmd() with
pending_req-se_cmd is an free after use bug..

So the way this should work is similar to how loopback currently does
things:

  - Move the kmem_cache_free() for pending_req from 
scsiback_do_resp_with_sense() to scsiback_release_cmd()
  - Remove the transport_generic_free_cmd() from scsiback_cmd_done()
  - Copy what tcm_loop_check_stop_free() does into 
scsiback_check_stop_free(), and remove target_put_sess_cmd()

 +static void scsiback_cmd_exec(struct vscsibk_pend *pending_req)
 +{
 + struct se_cmd *se_cmd = pending_req-se_cmd;
 + struct se_session *sess = pending_req-v2p-tpg-tpg_nexus-tvn_se_sess;
 + int rc;
 +
 + memset(pending_req-sense_buffer, 0, VSCSIIF_SENSE_BUFFERSIZE);
 +
 + 

Re: [PATCH V4 3/4] Introduce XEN scsiback module

2014-08-11 Thread Christoph Hellwig
 +#include scsi/scsi_dbg.h
 +#include scsi/scsi_eh.h
 +#include scsi/scsi_tcq.h

What do you need these for?  Normally target drivers shouldn't need
these.

 +struct vscsibk_emulate {
 + void (*pre_function)(struct vscsibk_pend *, void *);
 + void (*post_function)(struct vscsibk_pend *, void *);
 +};

This doesn't seem to be used.

 +#define scsiback_get(_b) (atomic_inc((_b)-nr_unreplied_reqs))
 +#define scsiback_put(_b) \
 + do {\
 + if (atomic_dec_and_test((_b)-nr_unreplied_reqs))  \
 + wake_up((_b)-waiting_to_free);\
 + } while (0)

Normal Linux style would be to make these inline functions.

 +static void scsiback_notify_work(struct vscsibk_info *info)
 +{
 + info-waiting_reqs = 1;
 + wake_up(info-wq);
 +}
 +
 +static irqreturn_t scsiback_intr(int irq, void *dev_id)
 +{
 + scsiback_notify_work((struct vscsibk_info *)dev_id);
 + return IRQ_HANDLED;
 +}

Seems like this driver should get the same threaded irq treatment as
the initiator side?

 +static void scsiback_disconnect(struct vscsibk_info *info)
 +{
 + if (info-kthread) {
 + kthread_stop(info-kthread);
 + info-kthread = NULL;
 + wake_up(info-shutdown_wq);
 + }
 +
 + wait_event(info-waiting_to_free,
 + atomic_read(info-nr_unreplied_reqs) == 0);
 +
 + if (info-irq) {
 + unbind_from_irqhandler(info-irq, info);
 + info-irq = 0;
 + }
 +
 + if (info-ring.sring) {
 + xenbus_unmap_ring_vfree(info-dev, info-ring.sring);
 + info-ring.sring = NULL;
 + }
 +}

Also the same treatment for goto based init failure unwinding.

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html