public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Jeff Garzik <jgarzik@pobox.com>
To: "Smart, James" <James.Smart@Emulex.com>
Cc: "'linux-scsi@vger.kernel.org'" <linux-scsi@vger.kernel.org>,
	"'linux-kernel@vger.kernel.org'" <linux-kernel@vger.kernel.org>
Subject: Re: [Announce] Emulex LightPulse Device Driver
Date: Wed, 10 Mar 2004 03:35:09 -0500	[thread overview]
Message-ID: <404ED33D.3070504@pobox.com> (raw)
In-Reply-To: <3356669BBE90C448AD4645C843E2BF2802C014D7@xbl.ma.emulex.com>

Smart, James wrote:
> All,
> 
> Emulex is embarking on an effort to open source the driver for its
> LightPulse Fibre Channel Adapter family. This effort will migrate Emulex's
> current code base to a driver centric to the Linux 2.6 kernel, with the goal
> to eventually gain inclusion in the base Linux kernel.
> 
> A new project has been created on SourceForge to host this effort - see
> http://sourceforge.net/projects/lpfcxxxx/ . Further information, such as the
> lastest FAQ, can be found on the project site.
> 
> We realize that this will be a significant effort for Emulex. We welcome any
> feedback that the community can provide us.

Embark you shall, and let me join in the chorus of kudos for making the 
leap to open source.  :)

I'm only part way through a review of the driver, but I felt there is a 
rather large and important issue that needs addressing...  "wrappers." 
These are a common tool for many hardware vendors, which allow one to 
more easily port a kernel driver across operating systems. 
Unfortunately, these sorts of abstractions continually lead to bugs.  In 
particular, the areas of locking, memory management, and PCI bus 
interaction are often most negatively affected.

In particular, here is an example of such a bug:

void
elx_sli_lock(elxHBA_t * phba, unsigned long *iflag)
{

         unsigned long flag;
         LINUX_HBA_t *lhba;

         flag = 0;
         lhba = (LINUX_HBA_t *) phba->pHbaOSEnv;
         spin_lock_irqsave(&lhba->slilock.elx_lock, flag);
         *iflag = flag;
         return;
}

It is not portable for code to return the value stored in the 'flags' 
argument of spin_lock_irqsave.  The usage _must_ be inlined.  This fails 
on, e.g., sparc64's register windows.

But this bug is only an example that serves to highlight the importance 
of directly using Linux API functions throughout your code.  It may 
sound redundant, but "Linux code should look like Linux code."  This 
emphasis on style may sound trivial, but it's important for 
review-ability, long term maintenance, and as we see here, bug prevention.

It may not be immediately apparent, but elimination of these wrappers 
also increases performance.  Many of the Linux API functions are inlined 
in key areas, intentionally, to improve performance.  By further 
wrapping these functions in non-inline functions of your own, you 
eliminate several compiler optimization opportunties.  In the case of 
spinlocks (above), you violate the API.

So I would like to see a slow unwinding, and elimination, of several of 
the wrappers in prod_linux.c.

1) elx_kmem_alloc, elx_kmem_free:  directly use kmalloc(size, 
GFP_KERNEL/ATOMIC) in the driver code.

2) eliminate all *_init_lock, *_lock, and *_unlock wrappers, and 
directly call the Linux spinlock primitives throughout your code.

3) strongly consider eliminating elx_read_pci_cmd, elx_read_pci, and 
simply calling the Linux PCI API directly from the lpfc driver code.

4) eliminate elx_sli_write_pci_cmd hook, elx_write_pci_cmd wrapper, and 
directly call the Linux PCI API in the code.

5) eliminate elx_remap_pci_mem, elx_unmap_pci_mem

6) fix unacceptably long delay in elx_sli_brdreset().  udelay() and 
mdelay() functions are meant for very small delays, since they do not 
reschedule.  Delays such as
         if (skip_post) {
                 mdelay(100);
         } else {
                 mdelay(2000);
         }
should be converted to timers or (if in kernel thread context) 
schedule_timeout().

7) eliminate elx_sli_pcimem_bcopy(,,sizeof(uint32_t)) in favor of "u32 
foo = readl()"

8) replace code such as
        ((SLI2_SLIM_t *) phba->slim2p.virt)->un.slim.pcb.hgpAddrHigh =
   (uint32_t) (psli->sliinit.elx_sli_read_pci) (phba, PCI_BAR_1_REGISTER);
   Laddr = (psli->sliinit.elx_sli_read_pci) (phba, PCI_BAR_0_REGISTER);
   Laddr &= ~0x4;
with calls to pci_resource_start() and/or pci_resource_len()

9) call pci_set_master() when you wish to enable PCI busmastering.  This 
will set the busmaster bit in PCI_COMMAND for you, as well as set up the 
PCI latency timer.

10) call pci_dma_sync functions rather than elx_pci_dma_sync()

That should get you started ;-)

	Jeff




  parent reply	other threads:[~2004-03-10  8:35 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-03-09 22:45 [Announce] Emulex LightPulse Device Driver Smart, James
2004-03-10  0:09 ` Stefan Smietanowski
2004-03-10  7:21   ` vda
2004-03-10  8:35 ` Jeff Garzik [this message]
2004-03-10 15:21   ` James Bottomley
     [not found] ` <mailman.1078908361.15239.linux-kernel2news@redhat.com>
2004-03-10 17:59   ` Pete Zaitcev
2004-03-10 18:04     ` Jeff Garzik
  -- strict thread matches above, loose matches on Subject: below --
2004-03-10 22:47 Smart, James
2004-03-11  1:10 ` James Bottomley

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=404ED33D.3070504@pobox.com \
    --to=jgarzik@pobox.com \
    --cc=James.Smart@Emulex.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-scsi@vger.kernel.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