netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
To: Michael Chan <mchan@broadcom.com>
Cc: David Miller <davem@davemloft.net>,
	michaelc@cs.wisc.edu, anilgv@broadcom.com,
	netdev <netdev@vger.kernel.org>,
	linux-scsi@vger.kernel.org, open-iscsi@googlegroups.com
Subject: Re: [PATCH 1/3] bnx2: Add support for CNIC driver.
Date: Thu, 22 May 2008 20:45:22 -0700	[thread overview]
Message-ID: <20080523034522.GA8612@linux.vnet.ibm.com> (raw)
In-Reply-To: <1211484208.18326.25.camel@dell>

On Thu, May 22, 2008 at 12:23:28PM -0700, Michael Chan wrote:
> 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.

So if a second CNIC driver attempts to register, it gets -EBUSY or
something, right?

> > > +
> > > +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.

OK.  Hmmm....  You cannot even get away with sarcasm these days!  ;-)

> > > +
> > > +	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.

OK.

> > > +
> > > +	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.

Trusting, but fair enough.  ;-)

> > > +	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.

Very good.  Could you please add a comment to that effect?  Otherwise
people search for what data structure is being freed up.

							Thanx, Paul

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

  reply	other threads:[~2008-05-23  3:45 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
2008-05-23  3:45           ` Paul E. McKenney [this message]
     [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=20080523034522.GA8612@linux.vnet.ibm.com \
    --to=paulmck@linux.vnet.ibm.com \
    --cc=anilgv@broadcom.com \
    --cc=davem@davemloft.net \
    --cc=linux-scsi@vger.kernel.org \
    --cc=mchan@broadcom.com \
    --cc=michaelc@cs.wisc.edu \
    --cc=netdev@vger.kernel.org \
    --cc=open-iscsi@googlegroups.com \
    /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).