netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Michael Chan" <mchan-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
To: paulmck-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org
Cc: "David Miller" <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>,
	michaelc-hcNo3dDEHLuVc3sceRu5cw@public.gmane.org,
	anilgv-dY08KVG/lbpWk0Htik3J/w@public.gmane.org,
	netdev <netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>,
	linux-scsi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	open-iscsi-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
Subject: Re: [PATCH 1/3] bnx2: Add support for CNIC driver.
Date: Thu, 22 May 2008 12:23:28 -0700	[thread overview]
Message-ID: <1211484208.18326.25.camel@dell> (raw)
In-Reply-To: <20080522064541.GA11933-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>


On Wed, 2008-05-21 at 23:45 -0700, Paul E. McKenney wrote:

> Some RCU-related questions interspersed below, for example, how are
> updates protected?

Only one CNIC driver will ever register with the BNX2 driver.  The main
purpose of using RCU is so that the fast path can avoid locking when
handling interrupt events from the hardware.

> > +
> > +static void bnx2_setup_cnic_irq_info(struct bnx2 *bp)
> > +{
> > +	struct cnic_ops *c_ops;
> > +	struct cnic_eth_dev *cp = &bp->cnic_eth_dev;
> > +	struct bnx2_napi *bnapi = &bp->bnx2_napi[0];
> > +	int sb_id;
> > +
> > +	rcu_read_lock();
> > +	c_ops = rcu_dereference(bp->cnic_ops);
> > +	if (!c_ops)
> > +		goto done;
> 
> Given that c_ops is unused below, what is happening here?  What prevents
> bp->cnic_ops from becoming NULL immediately after we test it?  And if
> it is OK for bp->cnic_ops to become NULL immediately after we test it,
> why are we bothering to test it?

You are right.  We should just unconditionally set up the IRQ
information without checking for c_ops.  The data structures we set up
below are owned by us.

> 
> > +
> > +	if (bp->flags & BNX2_FLAG_USING_MSIX) {
> > +		cp->drv_state |= CNIC_DRV_STATE_USING_MSIX;
> > +		bnapi->cnic_present = 0;
> > +		sb_id = BNX2_CNIC_VEC;
> > +		cp->irq_arr[0].irq_flags |= CNIC_IRQ_FL_MSIX;
> > +	} else {
> > +		cp->drv_state &= ~CNIC_DRV_STATE_USING_MSIX;
> > +		bnapi->cnic_tag = bnapi->last_status_idx;
> > +		bnapi->cnic_present = 1;
> > +		sb_id = 0;
> > +		cp->irq_arr[0].irq_flags &= !CNIC_IRQ_FL_MSIX;
> > +	}
> > +
> > +	cp->irq_arr[0].vector = bp->irq_tbl[sb_id].vector;
> > +	cp->irq_arr[0].status_blk = (void *) ((unsigned long) bp->status_blk +
> > +		(BNX2_SBLK_MSIX_ALIGN_SIZE * sb_id));
> > +	cp->irq_arr[0].status_blk_num = sb_id;
> > +	cp->num_irq = 1;
> > +
> > +done:
> > +	rcu_read_unlock();
> > +}
> > +
> > +static int bnx2_register_cnic(struct net_device *dev, struct cnic_ops *ops,
> > +			      void *data)
> > +{
> > +	struct bnx2 *bp = netdev_priv(dev);
> > +	struct cnic_eth_dev *cp = &bp->cnic_eth_dev;
> > +
> > +	if (ops == NULL)
> > +		return -EINVAL;
> > +
> > +	if (!try_module_get(ops->cnic_owner))
> > +		return -EBUSY;
> > +
> > +	bp->cnic_data = data;
> > +	rcu_assign_pointer(bp->cnic_ops, ops);
> 
> What prevents multiple tasks from doing this assignment concurrently?

As I said above, only one CNIC driver will ever register.

> 
> > +
> > +	cp->num_irq = 0;
> > +	cp->drv_state = CNIC_DRV_STATE_REGD;
> > +
> > +	bnx2_setup_cnic_irq_info(bp);
> > +
> > +	return 0;
> > +}
> > +
> > +static int bnx2_unregister_cnic(struct net_device *dev)
> > +{
> > +	struct bnx2 *bp = netdev_priv(dev);
> > +	struct bnx2_napi *bnapi = &bp->bnx2_napi[0];
> > +	struct cnic_eth_dev *cp = &bp->cnic_eth_dev;
> > +
> > +	cp->drv_state = 0;
> > +	module_put(bp->cnic_ops->cnic_owner);
> > +	bnapi->cnic_present = 0;
> > +	rcu_assign_pointer(bp->cnic_ops, NULL);
> 
> What prevents this from running concurrently with bnx2_register_cnic()?

We expect the CNIC driver to be well behaved and will only unregister
after successfully registered.

> 
> > +	synchronize_rcu();
> 
> The caller is responsible for freeing up the old bp->cnic_ops structure?
> Or is this structure statically allocated?
> 
> If so, is the idea to delay return until all prior calls through the
> old ops structure have completed?

The cnic_ops contain call back function pointers to the CNIC driver.  We
want to make sure that those calls have completed (in the fast path)
before continuing.

> 
> > +	return 0;
> > +}
> > +

  parent reply	other threads:[~2008-05-22 19:23 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-05-22  1:06 [PATCH 0/3] bnx2: Add iSCSI support Michael Chan
     [not found] ` <1211418386-18203-1-git-send-email-mchan-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
2008-05-22  1:06   ` [PATCH 1/3] bnx2: Add support for CNIC driver Michael Chan
2008-05-22  6:45     ` Paul E. McKenney
     [not found]       ` <20080522064541.GA11933-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
2008-05-22 19:23         ` Michael Chan [this message]
2008-05-23  3:45           ` Paul E. McKenney
     [not found]             ` <20080523034522.GA8612-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
2008-05-23  4:52               ` Michael Chan
2008-05-23  5:32                 ` Paul E. McKenney
     [not found]     ` <1211418386-18203-2-git-send-email-mchan-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
2008-05-22 15:18       ` Konrad Rzeszutek
2008-05-22  1:06   ` [PATCH 3/3] bnx2i: Add bnx2i iSCSI driver Michael Chan
     [not found]     ` <1211418386-18203-4-git-send-email-mchan-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
2008-05-22 15:15       ` Konrad Rzeszutek
2008-05-22 15:52         ` Ben Hutchings
2008-05-22 19:06         ` Anil Veerabhadrappa
2008-05-22 21:15     ` Christoph Hellwig
2008-05-22 22:59       ` Michael Chan
2008-05-23 20:23     ` Roland Dreier
2008-05-23 21:42       ` Anil Veerabhadrappa
2008-05-27 14:38         ` Roland Dreier
2008-05-27 19:17           ` Michael Chan
2008-05-27 18:21             ` Roland Dreier
2008-05-27 19:52           ` David Miller
2008-05-28  0:48             ` Michael Chan
2008-05-28  3:39               ` Jeff Garzik
2008-05-28  8:47                 ` Hannes Reinecke
2008-05-22  1:06 ` [PATCH 2/3] cnic: Add CNIC driver Michael Chan
2008-05-22  7:44   ` Paul E. McKenney
2008-05-22 19:46     ` Michael Chan
2008-05-23  3:47       ` Paul E. McKenney
2008-05-23 20:09   ` Roland Dreier
2008-05-23 20:14   ` Roland Dreier
2008-05-24  0:42     ` Michael Chan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1211484208.18326.25.camel@dell \
    --to=mchan-dy08kvg/lbpwk0htik3j/w@public.gmane.org \
    --cc=anilgv-dY08KVG/lbpWk0Htik3J/w@public.gmane.org \
    --cc=davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org \
    --cc=linux-scsi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=michaelc-hcNo3dDEHLuVc3sceRu5cw@public.gmane.org \
    --cc=netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=open-iscsi-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org \
    --cc=paulmck-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).