Re: [PATCH 3/3] tcm ibmvscsis driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, 2011-03-21 at 16:24 -0500, Brian King wrote:
> On 03/21/2011 04:01 PM, Nicholas A. Bellinger wrote:
> > On Mon, 2011-03-21 at 16:01 -0500, Brian King wrote:
> >> On 03/20/2011 08:09 PM, FUJITA Tomonori wrote:
> >>> Thanks for the testings,
> >>>
> >>> On Fri, 18 Mar 2011 15:58:53 -0500
> >>> Brian King <brking@xxxxxxxxxxxxxxxxxx> wrote:
> >>>
> >>>> On 03/07/2011 08:40 AM, James Bottomley wrote:
> >>>>> On Mon, 2011-03-07 at 13:41 +0900, FUJITA Tomonori wrote:
> >>>>>> On Sat, 12 Feb 2011 14:27:26 -0600
> >>>>>> James Bottomley <James.Bottomley@xxxxxxx> wrote:
> >>>>>>
> >>>>>>>> Disregard my previous comment. It looks like current client should handle reservations
> >>>>>>>> just fine without any further changes.
> >>>>>>>
> >>>>>>> So is that an ack for putting this in scsi-misc ... or did you want to
> >>>>>>> do more testing first?
> >>>>>>
> >>>>>> Ping,
> >>>>>>
> >>>>>> Brian, James, can we merge this during the next merge window?
> >>>>>
> >>>>> I'm still waiting for an ack from Brian.
> >>>>
> >>>> Sorry for the delay... I've got this loaded in the lab and have managed to oops
> >>>> a couple times. The first one was during shutdown, which I wasn't able to collect
> >>>> any data for. The most recent occurred when a client was trying to login for the
> >>>> first time:
> >>>
> >>> You mean that the kernel crashes every time when a client logs in?
> >>
> >> I think the crash I was seeing when the client logs in was just due to the fact that
> >> I had things misconfigured. It took me a bit to figure out the configfs stuff. Didn't
> >> realize at first I had to go off and manually create a lot of the configfs layout
> >> described in the wiki page. Once I did that, I was able to get a LUN to successfully
> >> report in on the client side. I'll start pounding on this a bit and see how things
> >> hold up.
> >>
> > 
> > Hi Brian,
> > 
> > If could send along the original misconfigured configfs layout that is
> > causing the OOPs in handle_crq(), I would be happy to have a quick look.
> 
> Here it is. As you can see, there is no ./target/ibmvscsis directory created. In order
> to get it to work, I did the following. Please let me know if there is a better way
> to do this...
> 
> cd /sys/kernel/configfs/target
> mkdir -p ibmvscsis/30000003/tpgt_1
> mkdir ibmvscsis/30000003/tpgt_1/lun/lun_0
> ln -s core/fileio_0/testfvd ibmvscsis/30000003/tpgt_1/lun/lun_0/default
> 

This is correct..

> I had previously created a file backed lun via:
> 
> tcm_node --fileio fileio_0/testfvd /vdisks/test 100000000
> 
> Thanks,
> 
> Brian
> 
> 

So indeed, the issue appears to be that handle_crq() is running w/o a
configured /sys/kernel/config/target/ibmvscsis/$VSCSI_WWN/tpgt_1/
endpoint, but still receiving incoming I/O via handle_crq() ->
handle_cmd_queue() -> tcm_queuecommand()..

Which means that tcm_queuecommand() and struct ibmvscsis_adapter need to
be aware of some form of state between I/O and control path in order to
prevent adapter->se_tpg and adapter->se_sess from being referenced
before the TPG endpoint and VIO I_T Nexus (TCM Session) has been setup
with the explict mkdir(2) operation via target_core_fabric_configfs.c:
target_fabric_make_tpg() -> ibmvscsis_make_tpg() code.

I recall it being mentioned at some point that certain VIO clients had
issue with the failure of the (initial..?) expected INQUIRY, for which
is handled internally in ibmvscsis_queuecommand() code..

So that said, I think we have a couple of options here..

*) Add a lock to protect adapter->se_sess for I/O and
ibmvscsis_make_tpg() control path code, and find a way to gracefully
handle tcm_queuecommand() exceptions for non-configured targets
endpoints after the internally emulated INQUIRY is completed.

*) Determine if breaking up individual external VIO setup logic makes
more sense from being done in a global manner for all available VIO
target connections via:

    module_init() ->
	ibmvscsis_init() ->
		vio_register_probe() -> 

into a more flexable method via individually configured
target_core_fabric_configfs.c:target_fabric_make_tpg()
-> ibmvscsis_make_tpg(), where we don't actually pull the current
ibmvscsis_probe() -> crq_queue_create() until mkdir -p
$VIO_TARGET_FULLPATH/tpgt_1 has been preformed.

Obviously for the long term direction of this code I would prefer the
the latter and a more flexiable direction (Tomo-san, thoughts on
this..?).

To prevent this from happening with existing code, I think the following
should address the current OOPs.  Please have a look and let me know.

Thanks!

--nab

diff --git a/drivers/scsi/ibmvscsi/ibmvscsis.c b/drivers/scsi/ibmvscsi/ibmvscsis.c
index 714af48..a0cd9b8 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsis.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsis.c
@@ -98,6 +98,9 @@ struct ibmvscsis_adapter {
 
        struct work_struct crq_work;
 
+       /* lock for protecting ->se_sess */
+       spinlock_t sess_lock;
+
        unsigned long liobn;
        unsigned long riobn;
 
@@ -335,6 +338,7 @@ static struct se_portal_group *ibmvscsis_make_tpg(struct se_wwn *wwn,
        struct ibmvscsis_adapter *adapter =
                container_of(wwn, struct ibmvscsis_adapter, tport_wwn);
        struct se_node_acl *acl;
+       struct se_session *se_sess;
        int ret;
        char *dname = (char *)dev_name(&adapter->dma_dev->dev);
 
@@ -347,16 +351,15 @@ static struct se_portal_group *ibmvscsis_make_tpg(struct se_wwn *wwn,
        if (ret)
                return ERR_PTR(-ENOMEM);
 
-       adapter->se_sess = transport_init_session();
-       if (!adapter->se_sess) {
+       se_sess = transport_init_session();
+       if (!se_sess) {
                core_tpg_deregister(&adapter->se_tpg);
                return ERR_PTR(-ENOMEM);
        }
 
        acl = core_tpg_check_initiator_node_acl(&adapter->se_tpg, dname);
        if (!acl) {
-               transport_free_session(adapter->se_sess);
-               adapter->se_sess = NULL;
+               transport_free_session(se_sess);
                return ERR_PTR(-ENOMEM);
        }
        adapter->se_sess->se_node_acl = acl;
@@ -365,6 +368,10 @@ static struct se_portal_group *ibmvscsis_make_tpg(struct se_wwn *wwn,
                                   adapter->se_sess->se_node_acl,
                                   adapter->se_sess, adapter);
 
+       spin_lock_bh(&adapter->sess_lock);
+       adapter->se_sess = se_sess;
+       spin_unlock_bh(&adapter->sess_lock);
+
        return &adapter->se_tpg;
 }
@@ -372,16 +379,19 @@ static void ibmvscsis_drop_tpg(struct se_portal_group *se_tpg)
 {
        struct ibmvscsis_adapter *adapter =
                container_of(se_tpg, struct ibmvscsis_adapter, se_tpg);
+       struct se_session *se_sess;
        unsigned long flags;
+       
+       transport_deregister_session_configfs(adapter->se_sess);
 
+       spin_lock_bh(&adapter->sess_lock);
+       se_sess = adapter->se_sess;
+       adapter->se_sess = NULL;
+       spin_unlock_bh(&adapter->sess_lock);
 
-       transport_deregister_session_configfs(adapter->se_sess);
        transport_free_session(adapter->se_sess);
-       core_tpg_deregister(se_tpg);
 
-       spin_lock_irqsave(&tpg_lock, flags);
-       adapter->se_sess = NULL;
-       spin_unlock_irqrestore(&tpg_lock, flags);
+       core_tpg_deregister(se_tpg);
 }
 
 static struct se_wwn *ibmvscsis_make_tport(struct target_fabric_configfs *tf,
@@ -873,6 +883,17 @@ static int tcm_queuecommand(struct ibmvscsis_adapter *adapter,
        data_len = srp_data_length(cmd, srp_cmd_direction(cmd));
 
        se_cmd = &vsc->se_cmd;
+       /*
+        * Ensure that an adapter>se_sess and TCM TPG endpoint have been
+        * configured via ibmvscsis_make_tpg().
+        */
+       spin_lock_bh(&adapter->sess_lock);
+       if (!adapter->se_sess) {
+               spin_unlock_bh(&adapter->sess_lock);
+               printk(KERN_ERR "struct ibmvscsis_adapter->se_sess has not been configured\n");
+               return -ENODEV:
+       }
+       spin_unlock_bh(&adapter->sess_lock);
 
        transport_init_se_cmd(se_cmd,
                              adapter->se_tpg.se_tpg_tfo,
@@ -1576,6 +1597,7 @@ static int ibmvscsis_probe(struct vio_dev *dev, const struct vio_device_id *id)
        if (!adapter)
                return -ENOMEM;
 
+       spin_lock_init(&adapter->sess_lock);
        adapter->dma_dev = dev;
 
        dma = (unsigned int *)vio_get_attribute(dev, "ibm,my-dma-window",


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


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux