All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: NGROUPS 2.6.2rc2
From: Rusty Russell @ 2004-01-28  1:12 UTC (permalink / raw)
  To: thockin, torvalds, Linux Kernel mailing list
In-Reply-To: <20040127225311.GA9155@sun.com>

In message <20040127225311.GA9155@sun.com> you write:
> (sorry if this dups, screwup in my aliases file)
> 
> Linus,

You should probably send to Andrew Morton, too (or instead).

For the record; it's overkill for what I need (hundreds, not thousands
of groups, and I don't really mind if accessing them is slow), but at
this point I'd just like *some* solution.

Thanks Tim!
Rusty.
--
  Anyone who quotes me in their sig is an idiot. -- Rusty Russell.

^ permalink raw reply

* Re: [Jfs-discussion] md raid + jfs + jfs_fsck
From: Theodore Ts'o @ 2004-01-28  2:47 UTC (permalink / raw)
  To: Christoph Hellwig, Dave Kleikamp, Florian Huber, JFS Discussion,
	linux-kernel
In-Reply-To: <20040127205324.A19913@infradead.org>

On Tue, Jan 27, 2004 at 08:53:24PM +0000, Christoph Hellwig wrote:
> Yes, it does.  But JFS should get the right size from the gendisk anyway.
> Or did you create the raid with the filesystem already existant?  While that
> appears to work for a non-full ext2/ext3 filesystem it's not something you
> should do because it makes the filesystem internal bookkeeping wrong and
> you'll run into trouble with any filesystem sooner or later.

The key words here is *appears* to work.  No matter what the
filesystem, as Chrisoph says, you'll run into trouble sooner or
later....

							- Ted

^ permalink raw reply

* Re: 2.6.2-rc2-bk1 oopses on boot (ACPI patch)
From: Andrew Morton @ 2004-01-28  2:42 UTC (permalink / raw)
  To: Alessandro Suardi; +Cc: linux-kernel, linux-acpi
In-Reply-To: <40171B5B.4020601@oracle.com>

Alessandro Suardi <alessandro.suardi@oracle.com> wrote:
>
> Already reported, but I'll do so once again, since it looks like
>   in a short while I won't be able to boot official kernels in my
>   current config...
> 
> Original report here:
> 
> http://www.ussg.iu.edu/hypermail/linux/kernel/0312.3/0442.html

Divide by zero.  Looks like ACPI is now passing bad values into the
frequency change notifier.

Does this make the oops go away?

diff -puN drivers/cpufreq/cpufreq.c~cpufreq-workaround drivers/cpufreq/cpufreq.c
--- 25/drivers/cpufreq/cpufreq.c~cpufreq-workaround	2004-01-27 18:36:05.000000000 -0800
+++ 25-akpm/drivers/cpufreq/cpufreq.c	2004-01-27 18:36:42.000000000 -0800
@@ -928,6 +928,11 @@ void cpufreq_notify_transition(struct cp
 		return;   /* Only valid if we're in the resume process where
 			   * everyone knows what CPU frequency we are at */
 
+	if (freqs->new == 0) {
+		printk("%s: avoiding div-by-zero\n", __FUNCTION__);
+		return;
+	}
+
 	down_read(&cpufreq_notifier_rwsem);
 	switch (state) {
 	case CPUFREQ_PRECHANGE:

_


^ permalink raw reply

* forwarding traffic from one port to another on the same box
From: Andrew @ 2004-01-28  2:37 UTC (permalink / raw)
  To: netfilter

I would like to forward all tcp traffic arriving on a particular port to 
another port on the same machine. This has worked for me in the past but 
I can't get it working on my current machine.

Here are the two commands I'm using to try to create the forward.

iptables -I FORWARD -p tcp -d 192.168.10.34 --dport 26 -j ACCEPT

iptables -t nat -A PREROUTING -p tcp -i eth0 -s 0/0 -d 192.168.10.34 
--dport 26 -j DNAT --to 192.168.10.34:25

The first command is accepted but the second command results in an 
'Invalid argument' error.

The computer has only one interface, eth0. Here are its particulars:
Mandrake Linux 9.2
Iptables 1.2.8
kernel 2.4.24 patched with super-freeswan 1.99.8

The value of /proc/sys/net/ipv4/conf/eth0/forwarding is 0. Changing it 
to 1 has no impact.
The value of /proc/sys/net/ipv4/conf/eth0/rp_filter is 0.

I hope someone out there has some ideas about what's going on because 
I'm all out.

Andrew




^ permalink raw reply

* Re: PATCH: (as177) Add class_device_unregister_wait() and platform_device_unregister_wait() to the driver model core
From: Roman Zippel @ 2004-01-28  2:36 UTC (permalink / raw)
  To: Rusty Russell; +Cc: viro, torvalds, stern, greg, linux-kernel, mochel
In-Reply-To: <20040128005801.5B1A92C12C@lists.samba.org>

Hi Rusty,

On Wed, 28 Jan 2004, Rusty Russell wrote:

> > Fixing this requires changing every single module, but in the end it
> > would be worth it, as it avoids the duplicated protection and we had
> > decent module unload semantics.
>
> And I still disagree. <shrug>

And I still don't know why. :(

> If it's any consolation, I don't plan any significant module work in
> 2.7.  If you want to work on this, you're welcome to it.  Perhaps you
> can convince Linus et al that it's worth the pain?

Well, the problem is that this won't be an one man show, it requires that
a number of kernel hackers understand the problem and the possible
solutions are discussed beforehand. I can understand that a lot here are
scared of such big change, but either we either continue complaining about
module unloading or we do something about it and this requires exploring
the various possibilities.
Rusty, you are the modules maintainer, you are supposed to understand
these issues, if you already block a discussion like that, what am I
supposed to expect from others? I really don't claim to have all the
answers and I really would like to discuss the various possible approaches
to solve this problem, so people also know what they can expect.

bye, Roman

^ permalink raw reply

* RE: [linux-lvm] mounting snapshot errors
From: R Dicaire @ 2004-01-28  2:30 UTC (permalink / raw)
  To: lvm
In-Reply-To: <9BBB7C9EFEF1874BAC4DC204E867EFAF02560F62@s99mail06>

On Tue, 2004-01-27 at 21:53, Little, Chris wrote:
> is the filesystem you are snapshotting still mounted when you execute the
> snapshot?  They need to be offline before the snapshot takes place.

Yes, they are still mounted when I take a snapshot, I must have missed that
in the docs, that in itself poses a problem as I then cant umount the volumes
without killing services. I'd understood the snapshotting process as being
able to snapshot a live filesystem, and then mount the snapshot to perform
backups from it instead of the live filesystem. Whats the purpose of the
--size arg to lvcreate when taking a snapshot, I thought it was a buffer
to hold data that'd normally be written to disk but cant when the
snapshot exists? I'm confused.

> -- 
>       aRDy Music
> http://www.ardynet.com

^ permalink raw reply

* Re: [LARTC] Problems with HTB (ceil being overpassed)
From: rubens @ 2004-01-28  2:20 UTC (permalink / raw)
  To: lartc
In-Reply-To: <opr2glxzfo4ddcy3@mail.elfarto.com.ar>


It seems you have hit timer innacuracy issues:
http://www.docum.org/stef.coene/qos/faq/cache/40.html

Rubens


On Tue, 27 Jan 2004, Gerardo Arceri wrote:

> We run a Hosting farm behind a bridge/iptables firewall setup running
> Gentoo with kernel 2.4.20-gentoo-r6, connected to a dual 15Mbps
> international internet pipe / , as this:
>
> Net Pipe --------- eth1 Bridge/Firewall eth0 -------- Internal Hosting
> Network
>
> lately we have been looking at htb to somehow control excessive usage from
> the users behind, but in our implementation there seems to be an error or
> something wrong on the setup,
> this is the test script i'm using, i know it's very rough but i think it
> should do the work.
>
> tc qdisc del dev eth1 root
> tc qdisc add dev eth1 root handle 1: htb default 10
> tc class add dev eth1 parent 1: classid 1:1 htb rate 98Mbit ceil 98Mbit
> tc class add dev eth1 parent 1:1 classid 1:10 htb rate 90Mbit ceil 90Mbit
> tc class add dev eth1 parent 1:1 classid 1:11 htb rate 2Mbit ceil 2Mbit
> tc class add dev eth1 parent 1:1 classid 1:12 htb rate 4Mbit ceil 4Mbit
> tc filter add dev eth1 protocol ip parent 1:0 prio 1 u32 match ip src
> $server_ip flowid 1:11
>
> I intend to limit $server_ip to 2Mbit max traffic ow, the problem is after
> i run the script htb seems to ignore the limit and traffic for the client
> stays in over 3mbit.
> but after a while of running with the htb active the server owner
> complains that the loading times of pages hosted on the server skyrocket
> and that ssh access becomes sluggish.
> Normally that server has about 4/5 Mbit/s of outgoing traffic measured by
> the iptables/mrtg script, doing a:
> #tc -s -d class show dev eth1
> shows:
>
> class htb 1:11 parent 1:1 prio 0 quantum 26214 rate 2Mbit ceil 2Mbit burst
> 2621b/8 mpu 0b cburst 2621b/8 mpu 0b level 0
>   Sent 23592359 bytes 26524 pkts (dropped 1579, overlimits 0)
>   rate 315631bps 352pps backlog 96p
>   lended: 26428 borrowed: 0 giants: 0
>   tokens: -3 ctokens: -3
>
> class htb 1:1 root rate 98Mbit ceil 98Mbit burst 64212b/8 mpu 0b cburst
> 64212b/8 mpu 0b level 7
>   Sent 66766024 bytes 97843 pkts (dropped 0, overlimits 0)
>   rate 889284bps 1291pps
>   lended: 0 borrowed: 0 giants: 0
>   tokens: 1 ctokens: 1
>
> class htb 1:10 parent 1:1 prio 0 quantum 200000 rate 90Mbit ceil 90Mbit
> burst 58970b/8 mpu 0b cburst 58970b/8 mpu 0b level 0
>   Sent 43271713 bytes 71415 pkts (dropped 0, overlimits 0)
>   rate 573411bps 938pps
>   lended: 71415 borrowed: 0 giants: 0
>   tokens: 1 ctokens: 1
>
> class htb 1:12 parent 1:1 prio 0 quantum 52428 rate 4Mbit ceil 4Mbit burst
> 2620b/8 mpu 0b cburst 2620b/8 mpu 0b level 0
>   Sent 0 bytes 0 pkts (dropped 0, overlimits 0)
>   lended: 0 borrowed: 0 giants: 0
>   tokens: 1 ctokens: 1
>
> Showing trafic in excess of 3.5 Mbit/s and coinciding with a mrtg graphic.
>
>  From my limited experience i would say that somehow my mrtg is measuring
> traffic well before it passes thru htb (which seems imposible from what
> i've read). i take the measurement on the
> iptables FORWARD chain:
>
> iptables -N $server_ip-in
> iptables -N $server_ip-out
> iptables -A $server_ip-in -j RETURN
> iptables -A $server_ip-out -j RETURN
> iptables -A FORWARD -s $server_ip -j $server_ip-out
> iptables -A FORWARD -d $server_ip -j $server_ip-in
>
> and to make the actual measurement:
> iptables -nvxL $server_ip-in
> iptables -nvxL $server_ip-out
>
> Resuming, how can i effectively test if and how well htb it's doing the
> job ?
>
>
> Help will be appreciated.
>
> _______________________________________________
> LARTC mailing list / LARTC@mailman.ds9a.nl
> http://mailman.ds9a.nl/mailman/listinfo/lartc HOWTO: http://lartc.org/
>

_______________________________________________
LARTC mailing list / LARTC@mailman.ds9a.nl
http://mailman.ds9a.nl/mailman/listinfo/lartc HOWTO: http://lartc.org/

^ permalink raw reply

* 2.6.2-rc2-bk1 oopses on boot (ACPI patch)
From: Alessandro Suardi @ 2004-01-28  2:15 UTC (permalink / raw)
  To: linux-kernel, linux-acpi; +Cc: Andrew Morton

Already reported, but I'll do so once again, since it looks like
  in a short while I won't be able to boot official kernels in my
  current config...

Original report here:

http://www.ussg.iu.edu/hypermail/linux/kernel/0312.3/0442.html

Please advise whether I should give up cpufreq for now - I really
  don't want to bang my head against a wall.


Thanks in advance,

--alessandro

  "Two rivers run too deep
   The seasons change and so do I"
       (U2, "Indian Summer Sky")


^ permalink raw reply

* Re: PATCH: (as177)  Add class_device_unregister_wait() and platform_device_unregister_wait() to the driver model core
From: viro @ 2004-01-28  2:17 UTC (permalink / raw)
  To: Roman Zippel
  Cc: Greg KH, Linus Torvalds, Alan Stern, Kernel development list,
	Patrick Mochel
In-Reply-To: <Pine.LNX.4.58.0401280252120.7851@serv>

On Wed, Jan 28, 2004 at 03:03:31AM +0100, Roman Zippel wrote:
> Hi,
> 
> On Tue, 27 Jan 2004, Greg KH wrote:
> 
> > > All this is done without a module count, this means that
> > > pci_unregister_driver() cannot return before the last reference is gone.
> > > For network devices this is not that much of a problem, as they can be
> > > rather easily deconfigured automatically, but that's not that easy for
> > > mounted block devices, so one has to be damned careful when to call the
> > > exit function.
> >
> > Um, not anymore.  I can yank out a mounted block device and watch the
> > scsi core recover just fine.  The need to make everything hotpluggable
> > has fixed up a lot of issues like this (as well as made more
> > problems...)
> 
> Recovery of the scsi core is IMO one the smallest problems, but how do you
> recover at the block layer? The point is that you have here theoretically
> more one recovery strategy, but simply pulling out the module leaves you
> not much room for a controlled recovery.

Block layer is not too big issue.  We have almost everything in the tree
already - the main problem is to get check_disk_change() use regularized.
Now, sound and character devices in general...

^ permalink raw reply

* Cheapest Prescript/ion D]rugs on the NET!
From: Doris Huff @ 2004-01-28  2:15 UTC (permalink / raw)
  To: kernel-janitors

[-- Attachment #1: Type: text/plain, Size: 2 bytes --]




[-- Attachment #2: Type: text/html, Size: 158 bytes --]

^ permalink raw reply

* Re: [uml-devel] Re: [PATCH] mconsole fixes
From: Dan Shearer @ 2004-01-28  2:16 UTC (permalink / raw)
  To: Jeff Dike; +Cc: user-mode-linux-devel
In-Reply-To: <200401280146.i0S1kaZw004957@ccure.user-mode-linux.org>

On Tue, Jan 27, 2004 at 08:46:36PM -0500, Jeff Dike wrote:
 
> > -    fprintf(stderr, "Sending command to '%s' : ", sun.sun_path);
> > -    perror("");
> > -    return;
> > +    if (strlen(sun.sun_path)==0) {
> > +      fprintf(stderr, "No connection exists, cannot send command.\n");
> > +    } else {
> > +      fprintf(stderr, "While sending command to '%s' : ", sun.sun_path);
> > +      perror("");
> > +    }
> > +    return(1);
> 
> I don't see the point of the strlen(sun.sun_path)==0 check, so I'm
> leaving that out until I see why it's necessary.

My idea was that there's a difference between an error on a connection
and no connection at all. Having no connection at all can happen very
easily, especially if you happen to use uml_dir on the cmdline which
triggers a bug that puts the file in the wrong place.

> I applied most of the rest of that.  I got rid of the exits from main, since
> I like returns better and I tidied up some other stuff.

Minor portability potential. See
http://www.eskimo.com/~scs/C-faq/q11.16.html. (I looked it up once long
ago and supposedly _exit is more likely to work on more systems than
exit.)

-- 
Dan Shearer
dan@shearer.org


-------------------------------------------------------
The SF.Net email is sponsored by EclipseCon 2004
Premiere Conference on Open Tools Development and Integration
See the breadth of Eclipse activity. February 3-5 in Anaheim, CA.
http://www.eclipsecon.org/osdn
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel

^ permalink raw reply

* Re: [PATCH] 2.6.2-rc2 - MPT Fusion driver 3.00.02 update
From: Jeremy Higdon @ 2004-01-28  2:11 UTC (permalink / raw)
  To: Douglas Gilbert
  Cc: Christoph Hellwig, James Bottomley, Moore, Eric Dean,
	SCSI Mailing List
In-Reply-To: <401627C3.20101@torque.net>

On Tue, Jan 27, 2004 at 06:56:35PM +1000, Douglas Gilbert wrote:
> Jeremy Higdon wrote:
> >On Mon, Jan 26, 2004 at 07:34:13PM +0000, Christoph Hellwig wrote:
> >
> >>On Mon, Jan 26, 2004 at 11:05:26AM -0600, James Bottomley wrote:
> >>
> >>>>I had avoided it due the comments in the code
> >>>>from sralston and pdelaney about sg interface 
> >>>>gererating wrong direction in some cases.  
> >>>
> >>>If you find a problem, I'll fix the generic code...
> >>
> >>I think it's just very old comments.  We had such a problem in early 2.4
> >>kernels, but it has been fixed for ages.  If it wasn't most of the scsi
> >>drivers would have a big problem.
> >
> >
> >Aren't there three interfaces for sg, or did the early ones go away
> >in 2.6?  I recall that we ran into trouble with sg setting the
> >direction incorrectly in 2.4 kernels when using older interface,
> >I think.
> 
> Jeremy,
> I can't see any such report in my changelogs for the sg
> driver during the lk 2.4 series. What was difficult with
> the older sg interface (sg_header based) was setting the
> command length as this was "guessed" from the first 3 bits
> of the opcode (SCSI_IOCTL_SEND_COMMAND ioctl still does this).
> 
> Doug Gilbert

Okay.  Here is where we ran into problems.

In sg_write(), if old_hdr.reply_len is greater than SZ_SG_HEADER,
then hp->dxfer_direction is set to SG_DXFER_TO_FROM_DEV.  Then
in sg_common_write(), if hp->dxfer_direction is SG_DXFER_TO_FROM_DEV,
then SRpnt->sr_data_direction is set to SCSI_DATA_READ.

For whatever reason, there seem to be apps out there that issue
SCSI data_out commands using the old interface and yet set the
reply_len in the old header to something larger than SZ_SG_HEADER.

Since we couldn't fix the app (it wasn't ours and we didn't have
source), we added code to our xscsi-scsi i/f.  It's a variation of
code that is in both the LSI and Qlogic drivers (borrowed from LSI,
as you can see from the comment).  Without it, some sg apps just
wouldn't work properly (the app in question that we had trouble
with was a Mylex RAID management tool).

So if you remove this code from the Fusion driver, some of these
things will stop working.  One answer would be to change the
apps, but that isn't really practical.  Another would be to put
this logic into sg, so that it's at least centralized.

jeremy

static int
xscsi_scsi_io_direction(Scsi_Cmnd *cmd)
{
        /*
         * Code borrowed from drivers/message/fusion/mptscsih.c::mptscsih_io_direction()
         * 09/23/2003 by Michael Reed, SGI:
         *    Copied, renamed, removed ifdef (and code) and tweaked.
         */

        switch (cmd->cmnd[0]) { /* hot path */
        case READ_6:
        case READ_10:
                return SCSI_DATA_READ;
                break;
        case WRITE_6:
        case WRITE_10:
                return SCSI_DATA_WRITE;
                break;
        }

        switch (cmd->cmnd[0]) {
        /*  _DATA_OUT commands  */
        case WRITE_LONG:        case WRITE_SAME:        case WRITE_BUFFER:
        case WRITE_12:          case WRITE_VERIFY:      case WRITE_VERIFY_12:
        case COMPARE:           case COPY:              case COPY_VERIFY:                                      
        case SEARCH_EQUAL:      case SEARCH_HIGH:       case SEARCH_LOW:                                       
        case SEARCH_EQUAL_12:   case SEARCH_HIGH_12:    case SEARCH_LOW_12:                                    
        case MODE_SELECT:       case MODE_SELECT_10:    case LOG_SELECT:                                       
        case SEND_DIAGNOSTIC:   case CHANGE_DEFINITION: case UPDATE_BLOCK:                                     
        case SET_WINDOW:        case MEDIUM_SCAN:       case SEND_VOLUME_TAG:                                  
        case REASSIGN_BLOCKS:   case PERSISTENT_RESERVE_OUT:                                                   
        case 0xea:              case 0xa3:                                                                     
                return SCSI_DATA_WRITE;                                                                        
                                                                                                               
        /*  No data transfer commands  */                                                                      
        case SEEK_6:            case SEEK_10:                                                                  
        case RESERVE:           case RELEASE:                                                                  
        case TEST_UNIT_READY:   case START_STOP:                                                               
        case ALLOW_MEDIUM_REMOVAL:                                                                             
                return SCSI_DATA_NONE;                                                                         
                                                                                                               
        /*  Conditional data transfer commands  */                                                             
        case FORMAT_UNIT:                                                                                      
                if (cmd->cmnd[1] & 0x10)        /* FmtData (data out phase)? */                                
                        return SCSI_DATA_WRITE;                                                                
                else                                                                                           
                        return SCSI_DATA_NONE;                                                                 
                                                                                                               
        case VERIFY:                                                                                           
                if (cmd->cmnd[1] & 0x02)        /* VERIFY:BYTCHK (data out phase)? */                          
                        return SCSI_DATA_WRITE;                                                                
                else                                                                                           
                        return SCSI_DATA_NONE;                                                                 
                                                                                                               
        case RESERVE_10:                                                                                       
                if (cmd->cmnd[1] & 0x03)        /* RESERVE:{LongID|Extent} (data out phase)? */                
                        return SCSI_DATA_WRITE;                                                                
                else                                                                                           
                        return SCSI_DATA_NONE;                                                                 
                                                                                                               
        /*  Covered write cases, presume read. */                                                              
        default:                                                                                               
                return SCSI_DATA_READ;                                                                         
        }                                                                                                      


^ permalink raw reply

* Re: [LARTC] tncg and bandwidth limiting
From: rubens @ 2004-01-28  2:12 UTC (permalink / raw)
  To: lartc
In-Reply-To: <5.2.0.9.0.20040127150331.00ac7bd0@mail.web-ster.com>



On Tue, 27 Jan 2004, Scott Baker wrote:

> I'm curious if some of the other experts out there wouldn't have a "better"
> way to do what I'm doing. I'd like to do HTB ingress as well, but it
> complains that the the ingress qdisc doesn't allow inside classes or
> something like that. I think this will work for me, I just want to make
> sure this is the best way to do things.

You don't need classes if you just want to shape traffic to a specific
rate. Use a classless qdisc like tbf:

tbf (mtu 1.5kB,limit 10kB,rate 1kBps,burst 2kB) {
    fifo;
}


Rubens


_______________________________________________
LARTC mailing list / LARTC@mailman.ds9a.nl
http://mailman.ds9a.nl/mailman/listinfo/lartc HOWTO: http://lartc.org/

^ permalink raw reply

* Re: PATCH: (as177)  Add class_device_unregister_wait() and platform_device_unregister_wait() to the driver model core
From: Roman Zippel @ 2004-01-28  2:03 UTC (permalink / raw)
  To: Greg KH; +Cc: Linus Torvalds, Alan Stern, Kernel development list,
	Patrick Mochel
In-Reply-To: <20040127202944.GE27240@kroah.com>

Hi,

On Tue, 27 Jan 2004, Greg KH wrote:

> > All this is done without a module count, this means that
> > pci_unregister_driver() cannot return before the last reference is gone.
> > For network devices this is not that much of a problem, as they can be
> > rather easily deconfigured automatically, but that's not that easy for
> > mounted block devices, so one has to be damned careful when to call the
> > exit function.
>
> Um, not anymore.  I can yank out a mounted block device and watch the
> scsi core recover just fine.  The need to make everything hotpluggable
> has fixed up a lot of issues like this (as well as made more
> problems...)

Recovery of the scsi core is IMO one the smallest problems, but how do you
recover at the block layer? The point is that you have here theoretically
more one recovery strategy, but simply pulling out the module leaves you
not much room for a controlled recovery.

bye, Roman

^ permalink raw reply

* Removal of ____raw_readq() and ____raw_writeq() from asm-mips/io.h
From: Kevin Paul Herbert @ 2004-01-28  1:58 UTC (permalink / raw)
  To: linux-mips

In edit 1.68, the non-interrupt locking versions of
raw_readq()/raw_writeq() were removed, in favor of locking ones. While
this makes sense in general, it breaks the compilation of the sb1250
which uses the non-locking versions (____raw_readq() and
____raw_writeq()) in interrupt handlers.

Personally, I think that it is very confusing to have so many similar
macros with similar names and increasing numbers of underscores, so I
don't really have a problem with this. I've modified
arch/mips/sibyte/sb1250/time.c and arch/mips/sibyte/sb1250/irq.c to use
the __ versions and have a few more instructions of overhead.

My question is whether this removal was intended or not, or whether
there are some other changes to the handlers in the sb1250-specific code
that got dropped somewhere.

If the consensus is that the ____ versions really should perish for the
sake of simplicity, I'll send my simple patches to the list to fix the
sb1250 build.

Thanks,
Kevin
-- 
Kevin Paul Herbert <kph@cisco.com>
cisco Systems, Inc.

^ permalink raw reply

* [RFC/PATCH, 2/4] readX_check() performance evaluation
From: Hironobu Ishii @ 2004-01-28  1:54 UTC (permalink / raw)
  To: linux-kernel, linux-ia64

This is a readX_check() prototype patch to evaluate
the performance disadvantage.

Thanks,
Hironobu Ishii
--------------------
diff -prN linux-2.6.1/drivers/message/fusion/Makefile linux-2.6.1.modified/drivers/message/fusion/Makefile
*** linux-2.6.1/drivers/message/fusion/Makefile 2004-01-09 15:59:45.000000000 +0900
--- linux-2.6.1.modified/drivers/message/fusion/Makefile 2004-01-26 20:25:21.691512363 +0900
***************
*** 15,20 ****
--- 15,23 ----
  
  EXTRA_CFLAGS += ${MPT_CFLAGS}
  
+ # for PCI_RECOVERY
+ EXTRA_CFLAGS += -DCONFIG_PCI_RECOVERY
+ 
  # Fusion MPT drivers; recognized debug defines...
  #  MPT general:
  #EXTRA_CFLAGS += -DDEBUG
*************** obj-$(CONFIG_FUSION)  += mptbase.o mptsc
*** 50,52 ****
--- 53,60 ----
  obj-$(CONFIG_FUSION_ISENSE) += isense.o
  obj-$(CONFIG_FUSION_CTL) += mptctl.o
  obj-$(CONFIG_FUSION_LAN) += mptlan.o
+ 
+ # for PCI error recovery
+ mptbase-objs := mptbase_main.o read_check.o
+ 
+ 
diff -prN linux-2.6.1/drivers/message/fusion/mptbase.c linux-2.6.1.modified/drivers/message/fusion/mptbase.c
*** linux-2.6.1/drivers/message/fusion/mptbase.c 2004-01-09 15:59:18.000000000 +0900
--- linux-2.6.1.modified/drivers/message/fusion/mptbase.c 2004-01-26 22:29:18.185561891 +0900
*************** struct _mpt_ioc_proc_list {
*** 260,265 ****
--- 260,305 ----
  
  #endif
  
+ 
+ #ifdef CONFIG_PCI_RECOVERY
+ /*
+  * Try to recover from PCI intermittent read errors
+  */
+ #define REG_READ_SUCCESS   0
+ 
+ #define REG_READ_OK        0
+ #define REG_READ_RETRY_OK  1
+ #define REG_READ_NG       -1
+ 
+ #define REG_READ_RETRY     5 /* retry limit */
+ 
+ extern inline int readl_check(volatile u32 *d, volatile u32 *a);
+ 
+ static inline int do_readl(volatile u32 *d, volatile u32 *a)
+ {
+  int  retry ;
+  int  fail = 0;
+ 
+  for (retry = REG_READ_RETRY; retry; retry--) {
+   if (readl_check(d, a) == REG_READ_SUCCESS) {
+    return (fail ? REG_READ_RETRY_OK : REG_READ_OK);
+   }
+   fail++;
+  }
+  /* retry out */
+  /* PCI reset? */
+  return REG_READ_NG;
+ }
+ 
+ static inline int CHIPREG_READ32(volatile u32 *d, volatile u32 *a)
+ {
+  if (PortIo) {
+   *d =inl((unsigned long)a);
+   return REG_READ_OK;
+  } else
+   return do_readl(d, a);
+ }
+ #else
  /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  /* 20000207 -sralston
   *  GRRRRR...  IOSpace (port i/o) register access (for the 909) is back!
*************** static inline u32 CHIPREG_READ32(volatil
*** 274,279 ****
--- 314,320 ----
   else
    return readl(a);
  }
+ #endif
  
  static inline void CHIPREG_WRITE32(volatile u32 *a, u32 v)
  {
*************** mpt_interrupt(int irq, void *bus_id, str
*** 352,360 ****
    */
   while (1) {
  
    if ((pa = CHIPREG_READ32(&ioc->chip->ReplyFifo)) == 0xFFFFFFFF)
     return IRQ_HANDLED;
! 
    cb_idx = 0;
    freeme = 0;
  
--- 393,413 ----
    */
   while (1) {
  
+ #ifdef CONFIG_PCI_RECOVERY
+   {
+    int read_fail;
+    read_fail = CHIPREG_READ32(&pa, &ioc->chip->ReplyFifo);
+    if (read_fail) {
+     printk("PCI PIO read error:%d\n", read_fail);
+     /* recovery code */
+    }
+    if (pa == 0xFFFFFFFF)
+     return IRQ_HANDLED;
+   }
+ #else
    if ((pa = CHIPREG_READ32(&ioc->chip->ReplyFifo)) == 0xFFFFFFFF)
     return IRQ_HANDLED;
! #endif
    cb_idx = 0;
    freeme = 0;
  
*************** mpt_send_handshake_request(int handle, i
*** 1066,1073 ****
--- 1119,1140 ----
    }
  
    /* Read doorbell and check for active bit */
+ #ifdef CONFIG_PCI_RECOVERY
+   {
+      int read_fail;
+      u32 dummy;
+      read_fail = CHIPREG_READ32(&dummy, &iocp->chip->Doorbell);
+      if (read_fail) {
+       printk("PCI PIO read error:%d\n", read_fail);
+       /* recovery code */
+      }
+      if (!(dummy & MPI_DOORBELL_ACTIVE))
+       return -5;
+   }
+ #else
    if (!(CHIPREG_READ32(&iocp->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
      return -5;
+ #endif
  
    dhsprintk((KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
      iocp->name, ii));
*************** mpt_GetIocState(MPT_ADAPTER *ioc, int co
*** 2170,2176 ****
--- 2237,2255 ----
   u32 s, sc;
  
   /*  Get!  */
+ #ifdef CONFIG_PCI_RECOVERY
+  {
+   int read_fail;
+   read_fail = CHIPREG_READ32(&s, &ioc->chip->Doorbell);
+   if (read_fail) {
+    printk("PCI PIO read error:%d\n", read_fail);
+    /* recovery code */
+   }
+  }
+ #else
   s = CHIPREG_READ32(&ioc->chip->Doorbell);
+ #endif
+ 
  // dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
   sc = s & MPI_IOC_STATE_MASK;
  
*************** mpt_downloadboot(MPT_ADAPTER *ioc, int s
*** 2871,2879 ****
--- 2950,2981 ----
   ddlprintk((MYIOC_s_INFO_FMT "DbGb0: downloadboot entered.\n",
      ioc->name));
  #ifdef MPT_DEBUG
+ #ifdef CONFIG_PCI_RECOVERY
+  {
+   int read_fail ;
+   read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+   if (read_fail) {
+    printk("PCI PIO read error:%d\n", read_fail);
+    /* recovery codes */
+   }
+  }
+ #else
   diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif
+ 
+ #ifdef CONFIG_PCI_RECOVERY
+  if (ioc->alt_ioc) {
+   int read_fail ;
+   read_fail = CHIPREG_READ32(&diag1val, &ioc->alt_ioc->chip->Diagnostic);
+   if (read_fail) {
+    printk("PCI PIO read error:%d\n", read_fail);
+    /* recovery code */
+   }
+  }
+ #else
   if (ioc->alt_ioc)
    diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ #endif
   ddlprintk((MYIOC_s_INFO_FMT "DbGb1: diag0=%08x, diag1=%08x\n",
      ioc->name, diag0val, diag1val));
  #endif
*************** mpt_downloadboot(MPT_ADAPTER *ioc, int s
*** 2903,2909 ****
--- 3005,3023 ----
   /* Write magic sequence to WriteSequence register
    * until enter diagnostic mode
    */
+ #ifdef CONFIG_PCI_RECOVERY
+  {
+   int read_fail;
+   read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+   if (read_fail) {
+    printk("PCI PIO error:%d\n", read_fail);
+    /* recovery code */
+   }
+  }
+ #else
   diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif
+ 
   while ((diag0val & MPI_DIAG_DRWE) == 0) {
    CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
    CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
*************** mpt_downloadboot(MPT_ADAPTER *ioc, int s
*** 2928,2937 ****
--- 3042,3075 ----
  
    }
  
+ #ifdef CONFIG_PCI_RECOVERY
+   {
+    int read_fail ;
+    read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+    if (read_fail) {
+     printk("PCI PIO read error:%d\n", read_fail);
+     /* recovery code */
+    }
+   }
+ #else
    diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif
+ 
  #ifdef MPT_DEBUG
+ #ifdef CONFIG_PCI_RECOVERY
+   if (ioc->alt_ioc)  {
+    int read_fail;
+    read_fail = CHIPREG_READ32(&diag1val, &ioc->alt_ioc->chip->Diagnostic);
+    if (read_fail) {
+     printk("PCI PIO read error:%d\n", read_fail);
+     /* recovery code */
+    }
+   }
+ #else
    if (ioc->alt_ioc)
     diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ #endif
+ 
    ddlprintk((MYIOC_s_INFO_FMT "DbGb3: diag0=%08x, diag1=%08x\n",
      ioc->name, diag0val, diag1val));
  #endif
*************** mpt_downloadboot(MPT_ADAPTER *ioc, int s
*** 2944,2951 ****
--- 3082,3100 ----
   CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
  
  #ifdef MPT_DEBUG
+ #ifdef CONFIG_PCI_RECOVERY
+  if (ioc->alt_ioc) {
+   int read_fail;
+   read_fail = CHIPREG_READ32(&diag1val, &ioc->alt_ioc->chip->Diagnostic);
+   if (read_fail) {
+    printk("PCI PIO read error:%d\n", read_fail);
+    /* recovery code */
+   }
+  }
+ #else
   if (ioc->alt_ioc)
    diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ #endif
  
   ddlprintk((MYIOC_s_INFO_FMT "DbGb3: diag0=%08x, diag1=%08x\n",
     ioc->name, diag0val, diag1val));
*************** mpt_downloadboot(MPT_ADAPTER *ioc, int s
*** 3097,3103 ****
--- 3246,3265 ----
   CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
  
   /* clear the RW enable and DISARM bits */
+ #ifdef CONFIG_PCI_RECOVERY
+  {
+   int read_fail ;
+ 
+   read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+   if (read_fail) {
+    printk("PCI PIO read error:%d\n", read_fail);
+    /* recovery code */
+   }
+  }
+ #else
   diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif
+ 
   diag0val &= ~(MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE | MPI_DIAG_FLASH_BAD_SIG);
   CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
  
*************** mpt_diag_reset(MPT_ADAPTER *ioc, int ign
*** 3215,3225 ****
--- 3377,3410 ----
   CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
  
   /* Use "Diagnostic reset" method! (only thing available!) */
+ #ifdef CONFIG_PCI_RECOVERY
+  {
+   int read_fail;
+   read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+   if (read_fail) {
+    printk("PCI PIO read error:%d\n", read_fail);
+    /* recovery code */
+   }
+  }
+ #else
   diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif
  
  #ifdef MPT_DEBUG
+ #ifdef CONFIG_PCI_RECOVERY
+  if (ioc->alt_ioc) {
+   int read_fail;
+   read_fail = CHIPREG_READ32(&diag1val, &ioc->alt_ioc->chip->Diagnostic);
+   if (read_fail) {
+    printk("PCI PIO read error:%d\n", read_fail);
+    /* recovery code */
+   }
+  }
+ #else
   if (ioc->alt_ioc)
    diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ #endif
+ 
   dprintk((MYIOC_s_INFO_FMT "DbG1: diag0=%08x, diag1=%08x\n",
     ioc->name, diag0val, diag1val));
  #endif
*************** mpt_diag_reset(MPT_ADAPTER *ioc, int ign
*** 3255,3269 ****
--- 3440,3477 ----
  
     }
  
+ #ifdef CONFIG_PCI_RECOVERY
+    {
+     int read_fail;
+     read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+     if (read_fail) {
+      printk("PCI PIO read error:%d\n", read_fail);
+      /* recovery code */
+     }
+    }
+ #else
     diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif
  
     dprintk((MYIOC_s_INFO_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
       ioc->name, diag0val));
    }
  
  #ifdef MPT_DEBUG
+ #ifndef CONFIG_PCI_RECOVERY
+   if (ioc->alt_ioc) {
+    int read_fail;
+    read_fail = CHIPREG_READ32(&diag1val, &ioc->alt_ioc->chip->Diagnostic);
+    if (read_fail) {
+     printk("PCI PIO read error:%d\n", read_fail);
+     /* recovery code */
+    }
+   }
+ #else
    if (ioc->alt_ioc)
     diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ #endif
+ 
    dprintk((MYIOC_s_INFO_FMT "DbG2: diag0=%08x, diag1=%08x\n",
      ioc->name, diag0val, diag1val));
  #endif
*************** mpt_diag_reset(MPT_ADAPTER *ioc, int ign
*** 3320,3329 ****
--- 3528,3561 ----
      * case.  _diag_reset will return < 0
      */
     for (count = 0; count < 30; count ++) {
+ #ifdef CONFIG_PCI_RECOVERY
+     {
+      int read_fail;
+      read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+      if (read_fail) {
+       printk("PCI PIO read error:%d\n", read_fail);
+       /* recovery code */
+      }
+     }
+ #else
      diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif
+ 
  #ifdef MPT_DEBUG
+ #ifdef CONFIG_PCI_RECOVERY
+     if (ioc->alt_ioc) {
+      int read_fail;
+      read_fail = CHIPREG_READ32(&diag1val, &ioc->alt_ioc->chip->Diagnostic);
+      if (read_fail) {
+       printk("PCI PIO read error:%d\n", read_fail);
+       /* recovery code */
+      }
+     }
+ #else
      if (ioc->alt_ioc)
       diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ #endif
+ 
      dprintk((MYIOC_s_INFO_FMT
       "DbG2b: diag0=%08x, diag1=%08x\n",
       ioc->name, diag0val, diag1val));
*************** mpt_diag_reset(MPT_ADAPTER *ioc, int ign
*** 3353,3359 ****
--- 3585,3603 ----
      * with calling program.
      */
     for (count = 0; count < 30; count ++) {
+ #ifdef CONFIG_PCI_RECOVERY
+     {
+      int read_fail;
+      read_fail = CHIPREG_READ32(&doorbell, &ioc->chip->Doorbell);
+      if (read_fail) {
+       printk("PCI PIO read error:%d\n", read_fail);
+       /* recovery code */
+      }
+     }
+ #else
      doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
+ #endif
+ 
      doorbell &= MPI_IOC_STATE_MASK;
  
      if (doorbell == MPI_IOC_STATE_READY) {
*************** mpt_diag_reset(MPT_ADAPTER *ioc, int ign
*** 3371,3380 ****
--- 3615,3648 ----
    }
   }
  
+ #ifdef CONFIG_PCI_RECOVERY
+  {
+   int read_fail;
+   read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+   if (read_fail) {
+    printk("PCI PIO read error:%d\n", read_fail);
+    /* recovery code */
+   }
+  }
+ #else
   diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif
+ 
  #ifdef MPT_DEBUG
+ #ifdef CONFIG_PCI_RECOVERY
+  if (ioc->alt_ioc) {
+   int read_fail;
+   read_fail = CHIPREG_READ32(&diag1val, &ioc->alt_ioc->chip->Diagnostic);
+   if (read_fail) {
+    printk("PCI PIO read error:%d\n", read_fail);
+    /* recovery code */
+   }
+  }
+ #else
   if (ioc->alt_ioc)
    diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ #endif
+ 
   dprintk((MYIOC_s_INFO_FMT "DbG3: diag0=%08x, diag1=%08x\n",
    ioc->name, diag0val, diag1val));
  #endif
*************** mpt_diag_reset(MPT_ADAPTER *ioc, int ign
*** 3382,3388 ****
--- 3650,3668 ----
   /* Clear RESET_HISTORY bit!  Place board in the
    * diagnostic mode to update the diag register.
    */
+ #ifdef CONFIG_PCI_RECOVERY
+  {
+   int read_fail;
+   read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+   if (read_fail) {
+    printk("PCI PIO read error:%d\n", read_fail);
+    /* recovery code */
+   }
+  }
+ #else
   diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif
+ 
   count = 0;
   while ((diag0val & MPI_DIAG_DRWE) == 0) {
    /* Write magic sequence to WriteSequence register
*************** mpt_diag_reset(MPT_ADAPTER *ioc, int ign
*** 3408,3418 ****
--- 3688,3722 ----
       ioc->name, diag0val);
     break;
    }
+ #ifdef CONFIG_PCI_RECOVERY
+   {
+    int read_fail;
+    read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+    if (read_fail) {
+     printk("PCI PIO read error:%d\n", read_fail);
+     /* recovery code */
+    }
+   }
+ #else
    diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif
+ 
   }
   diag0val &= ~MPI_DIAG_RESET_HISTORY;
   CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
+ #ifdef CONFIG_PCI_RECOVERY
+  {
+   int read_fail;
+   read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+   if (read_fail) {
+    printk("PCI PIO read error:%d\n", read_fail);
+    /* recovery code */
+   }
+  }
+ #else
   diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif
+ 
   if (diag0val & MPI_DIAG_RESET_HISTORY) {
    printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
      ioc->name);
*************** mpt_diag_reset(MPT_ADAPTER *ioc, int ign
*** 3424,3430 ****
--- 3728,3746 ----
  
   /* Check FW reload status flags.
    */
+ #ifdef CONFIG_PCI_RECOVERY
+  {
+   int read_fail;
+   read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+   if (read_fail) {
+    printk("PCI PIO read error:%d\n", read_fail);
+    /* recovery code */
+   }
+  }
+ #else
   diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif
+ 
   if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
    printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
      ioc->name, diag0val);
*************** mpt_diag_reset(MPT_ADAPTER *ioc, int ign
*** 3432,3439 ****
--- 3748,3767 ----
   }
  
  #ifdef MPT_DEBUG
+ #ifdef CONFIG_PCI_RECOVERY
+  if (ioc->alt_ioc) {
+   int read_fail;
+   read_fail = CHIPREG_READ32(&diag1val, &ioc->chip->Diagnostic);
+   if (read_fail) {
+    printk("PCI PIO read error:%d\n", read_fail);
+    /* recovery code */
+   }
+  }
+ #else
   if (ioc->alt_ioc)
    diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ #endif
+ 
   dprintk((MYIOC_s_INFO_FMT "DbG4: diag0=%08x, diag1=%08x\n",
     ioc->name, diag0val, diag1val));
  #endif
*************** mpt_handshake_req_reply_wait(MPT_ADAPTER
*** 3743,3750 ****
--- 4071,4092 ----
     ioc->name, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
  
   /* Read doorbell and check for active bit */
+ #ifdef CONFIG_PCI_RECOVERY
+  {
+   int read_fail;
+   u32 dummy;
+   read_fail = CHIPREG_READ32(&dummy, &ioc->chip->Doorbell);
+   if (read_fail) {
+    printk("PCI PIO read error:%d\n", read_fail);
+    /* recovery code */
+   }
+   if (!(dummy & MPI_DOORBELL_ACTIVE))
+    return -1;
+  }
+ #else
   if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
     return -1;
+ #endif
  
   /*
    * Clear doorbell int (WRITE 0 to IntStatus reg),
*************** WaitForDoorbellAck(MPT_ADAPTER *ioc, int
*** 3822,3828 ****
--- 4164,4182 ----
  
   if (sleepFlag == CAN_SLEEP) {
    while (--cntdn) {
+ #ifdef CONFIG_PCI_RECOVERY
+    {
+     int read_fail;
+     read_fail = CHIPREG_READ32(&intstat, &ioc->chip->IntStatus);
+     if (read_fail) {
+      printk("PCI PIO read error:%d\n", read_fail);
+      /* recovery code */
+        }
+    }
+ #else
     intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
+ #endif
+ 
     if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
      break;
     set_current_state(TASK_INTERRUPTIBLE);
*************** WaitForDoorbellAck(MPT_ADAPTER *ioc, int
*** 3831,3837 ****
--- 4185,4203 ----
    }
   } else {
    while (--cntdn) {
+ #ifdef CONFIG_PCI_RECOVERY
+    {
+     int read_fail;
+     read_fail = CHIPREG_READ32(&intstat, &ioc->chip->IntStatus);
+     if (read_fail) {
+      printk("PCI PIO read error:%d\n", read_fail);
+      /* recovery code */
+     }
+    }
+ #else
     intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
+ #endif
+ 
     if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
      break;
     mdelay (1);
*************** WaitForDoorbellInt(MPT_ADAPTER *ioc, int
*** 3872,3878 ****
--- 4238,4256 ----
   cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong;
   if (sleepFlag == CAN_SLEEP) {
    while (--cntdn) {
+ #ifdef CONFIG_PCI_RECOVERY
+    {
+     int read_fail;
+     read_fail = CHIPREG_READ32(&intstat, &ioc->chip->IntStatus);
+     if (read_fail) {
+      printk("PCI PIO read error:%d\n", read_fail);
+      /* recovery code */
+     }
+    }
+ #else
     intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
+ #endif
+ 
     if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
      break;
     set_current_state(TASK_INTERRUPTIBLE);
*************** WaitForDoorbellInt(MPT_ADAPTER *ioc, int
*** 3881,3887 ****
--- 4259,4277 ----
    }
   } else {
    while (--cntdn) {
+ #ifdef CONFIG_PCI_RECOVERY
+    {
+     int read_fail;
+     read_fail = CHIPREG_READ32(&intstat, &ioc->chip->IntStatus);
+     if (read_fail) {
+      printk("PCI PIO read error:%d\n", read_fail);
+      /* recovery code */
+     }
+    }
+ #else
     intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
+ #endif
+ 
     if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
      break;
     mdelay(1);
*************** WaitForDoorbellReply(MPT_ADAPTER *ioc, i
*** 3932,3943 ****
--- 4322,4361 ----
   if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
    failcnt++;
   } else {
+ #ifdef CONFIG_PCI_RECOVERY
+   {
+    int read_fail;
+    u32 dummy;
+    read_fail = CHIPREG_READ32(&dummy, &ioc->chip->Doorbell);
+    if (read_fail) {
+     printk("PCI PIO read error:%d\n", read_fail);
+     /* recovery code */
+    }
+    hs_reply[u16cnt++] = le16_to_cpu(dummy & 0x0000FFFF);
+   }
+ #else
    hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
+ #endif
+ 
    CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
    if ((t = WaitForDoorbellInt(ioc, 2, sleepFlag)) < 0)
     failcnt++;
    else {
+ #ifdef CONFIG_PCI_RECOVERY
+    {
+     int read_fail;
+     u32 dummy;
+     read_fail = CHIPREG_READ32(&dummy, &ioc->chip->Doorbell);
+     if (read_fail) {
+      printk("PCI PIO read error:%d\n", read_fail);
+      /* recovery code */
+     }
+     hs_reply[u16cnt++] = le16_to_cpu(dummy & 0x0000FFFF);
+    }
+ #else
     hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
+ #endif
+ 
     CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
    }
   }
*************** WaitForDoorbellReply(MPT_ADAPTER *ioc, i
*** 3953,3959 ****
--- 4371,4391 ----
   for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
    if ((t = WaitForDoorbellInt(ioc, 2, sleepFlag)) < 0)
     failcnt++;
+ #ifdef CONFIG_PCI_RECOVERY
+   {
+    int read_fail;
+    u32 dummy;
+    read_fail = CHIPREG_READ32(&dummy, &ioc->chip->Doorbell);
+    if (read_fail) {
+     printk("PCI PIO read error:%d\n", read_fail);
+     /* recovery code */
+    }
+    hword = le16_to_cpu(dummy & 0x0000FFFF);
+   }
+ #else
    hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
+ #endif
+ 
    /* don't overflow our IOC hs_reply[] buffer! */
    if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
     hs_reply[u16cnt] = hword;
*************** fusion_init(void)
*** 5896,5901 ****
--- 6328,6339 ----
   show_mptmod_ver(my_NAME, my_VERSION);
   printk(KERN_INFO COPYRIGHT "\n");
  
+ #ifdef CONFIG_PCI_RECOVERY
+         printk(KERN_INFO "Enable PCI PIO read error recovery\n");
+ #else
+         printk(KERN_INFO "Disable PCI PIO read error recovery\n");
+ #endif
+ 
   Q_INIT(&MptAdapters, MPT_ADAPTER);   /* set to empty */
   for (i = 0; i < MPT_MAX_PROTOCOL_DRIVERS; i++) {
    MptCallbacks[i] = NULL;
*************** fusion_exit(void)
*** 5962,5968 ****
--- 6400,6418 ----
    /* Clear any lingering interrupt */
    CHIPREG_WRITE32(&this->chip->IntStatus, 0);
  
+ #ifdef CONFIG_PCI_RECOVERY
+   {
+    int read_fail;
+    u32 dummy;
+    read_fail = CHIPREG_READ32(&dummy, &this->chip->IntStatus);
+    if (read_fail) {
+     printk("PCI PIO read error:%d\n", read_fail);
+     /* recovery code */
+    }
+   }
+ #else
    CHIPREG_READ32(&this->chip->IntStatus);
+ #endif
  
    Q_DEL_ITEM(this);
    mpt_adapter_dispose(this);
diff -prN linux-2.6.1/drivers/message/fusion/mptbase.h linux-2.6.1.modified/drivers/message/fusion/mptbase.h
*** linux-2.6.1/drivers/message/fusion/mptbase.h 2004-01-09 15:59:10.000000000 +0900
--- linux-2.6.1.modified/drivers/message/fusion/mptbase.h 2004-01-26 16:41:43.394801737 +0900
***************
*** 80,87 ****
  #define COPYRIGHT "Copyright (c) 1999-2003 " MODULEAUTHOR
  #endif
  
! #define MPT_LINUX_VERSION_COMMON "2.05.00.05"
! #define MPT_LINUX_PACKAGE_NAME  "@(#)mptlinux-2.05.00.05"
  #define WHAT_MAGIC_STRING  "@" "(" "#" ")"
  
  #define show_mptmod_ver(s,ver)  \
--- 80,87 ----
  #define COPYRIGHT "Copyright (c) 1999-2003 " MODULEAUTHOR
  #endif
  
! #define MPT_LINUX_VERSION_COMMON "2.05.00.05PCI"
! #define MPT_LINUX_PACKAGE_NAME  "@(#)mptlinux-2.05.00.05PCI"
  #define WHAT_MAGIC_STRING  "@" "(" "#" ")"
  
  #define show_mptmod_ver(s,ver)  \
diff -prN linux-2.6.1/drivers/message/fusion/read_check.S linux-2.6.1.modified/drivers/message/fusion/read_check.S
*** linux-2.6.1/drivers/message/fusion/read_check.S 1970-01-01 09:00:00.000000000 +0900
--- linux-2.6.1.modified/drivers/message/fusion/read_check.S 2004-01-26 22:19:20.426780151 +0900
***************
*** 0 ****
--- 1,69 ----
+ #define ENTRY(name) \
+  .align 32; \
+  .global name; \
+  .proc name; \
+ name:
+ #define END(name) \
+  .endp name
+  
+ /****************************************************************************/
+  .rodata
+  .align 8
+  .global readchk_addrs
+ readchk_addrs:
+  data8 .readl_start#
+  data8 .readl_end#
+ 
+  /* This should be per CPU data */
+  .global readl_mca#
+  .sbss
+  .align 4
+  .type readl_mca#,@object
+  .size readl_mca#,4
+ readl_mca:
+  .skip 4
+ /*
+  *
+  * int readl_check( __u32 *valp, __u32 *addr ) ;
+  *     in0,           in1
+  */
+  .text
+  .align 16
+ ENTRY(readl_check)
+  .prologue
+  .body
+ {.mmi addl r15 = @ltoffx(readl_mca#), r1
+  ;;
+  ld8.mov r14 = [r15], readl_mca#  /* r14 = &readl_mca */
+  nop.i 0
+  ;;
+ }
+ .readl_start:
+ {.mmi ld4.acq r15 = [r14]  /* r15 = readl_mca */
+  ld4 r33 = [r33]  /* r33 = *addr(r33) */
+  nop.i 0
+  ;;
+ }
+ {.mmi add r16 =1, r33  /* consume r33 */
+  nop.m 0
+  nop.i 0
+  ;;
+ }
+ .readl_end:
+ {.mmi ld4.acq r14 = [r14]  /* r14 = readl_mca */
+  ;;
+  cmp4.ne p6, p7 = r14, r15 /* old readl_mca == readl_mca? */
+  nop.i 0
+  ;;
+ }
+ {.mmi (p7) st4 [r32] = r33  /* if (old==new) *valp(r32) = r33 */
+  (p7) mov r8 = r0  /* if (old==new) ret = 0 */
+  nop.i 0
+ }
+ {.mmb (p6) addl r8 = 1, r0  /* if (old!=new) ret = 1 */
+  nop.m 0
+  br.ret.sptk.many rp
+  ;;
+ }
+ 
+ END(readl_check)


^ permalink raw reply

* [RFC/PATCH, 3/4] readX_check() performance evaluation
From: Hironobu Ishii @ 2004-01-28  1:54 UTC (permalink / raw)
  To: linux-kernel, linux-ia64

This is a patch for rawread 1.0.3.
Original rawread 1.0.3 depends on i386.

Thanks, 
Hironobu Ishii

--- rawread.c.old 2004-01-22 19:33:43.000000000 +0900
+++ rawread.c 2004-01-27 23:26:24.406717936 +0900
@@ -94,8 +94,14 @@
 
 __inline__ unsigned long long int rdtsc()
 {
-  unsigned long long int x;
-  __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
+ unsigned long long int x;
+#if __i386__
+ __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
+#elif __ia64__
+ __asm__ volatile ("mov r8 = ar44");
+#else
+ #error "Please write your own rdtsc()"
+#endif
   return x;
 }
 


^ permalink raw reply

* [RFC/PATCH, 4/4] readX_check() performance evaluation
From: Hironobu Ishii @ 2004-01-28  1:54 UTC (permalink / raw)
  To: linux-kernel, linux-ia64

This is our goal and plan.

Our goal:
    - We'd like to recover from PCI-X intermittent errors
      as possible as we can.
      We'd like to recvoer from following errors
         a) PIO read data parity errors
         b) PIO write data parity erros
         c) DMA read data parity errors
         d) DMA write data parity erros
      (PIO means that the initiator is the CPU,
      DMA means that the initiator is the device.)
    - If a fatal bus error like SERR occurs, we'd like to shutdown 
      the failed bus(, remove driver instances) and continue 
      system operation.
    - If there are readX_check() I/F, we can safely perform 
      PHP(PCI Hotplug) operation.
      Currently there is no reliable I/F to check the newly 
      installed card, so to speak, PHP is the same as the gambling.

Our Plan:
    - Recover from Data parity error
        Currently, we are focused on ia64 architecture.

        Device setup assumption:
          PCI command register/ Parity error response =1
          PCI-X command register/ Data parity error recovery=1

        a) PIO read data parity error recovery
          (Memory mapped I/O read error recovery)

          - readX_check() read the memory mapped hardware
            and consume the data by additional instruction.
          - If there were data parity error, machine check will
            occurs.  Local machine check handler check whether 
            the exception was caused by readX_check() 
            and increment a per-CPU MCA counter variable.
            Then handler returns.
          - readX_check check the per-CPU MCA counter variable.
            When the counter is incremented, return an error.
          - If readX_check() returns an error and if reading 
            the register has no side-effect, re-read the register
            a few times to recover from the error.
            If reading the register has a side-effect, driver may
            reset the HW and restart operation.

        b) PIO write data parity error recovery
          (Memory mapped I/O write error recovery)
          
          - The device will find a parity error.
            When the device find a parity error, 
            it reports the error in the PCI status 
            register as "Detected Parity Error == 1".
            After the driver did some PIO writes,
            the driver can notice the error by reading
            the PCI staus register.
          - If writing to the register has no side-effect,
            the driver can re-writeto the register.
            If writing the register has a side-effect,
            driver may reset the HW and restart operation.

        c) DMA read data parity errors
           (DMA from memory to device)

          - The device will find a parity error.
            When the device detected a data parity error,
            it set the "Detected Parity Error == 1".

            After a while, the driver check the PCI status
            register, and knows that there was a data parity error.
          - Because the driver can't decide which I/O failed
            precisely, the recovery method will be reseting the HW
            and restarting the I/O if possible.

        d) DMA write data parity erros
           (DMA from device to memory)

           - Host bridge detect the data parity error,
             and assert PERR signal on the bus.
             Then the device will notice the error and 
             report it in PCI status register as 
             "Master Data Parity error == 1".
          - Because the driver can't decide which I/O failed
            precisely, the recovery method will be reseting the HW
            and restarting the I/O if possible.

    - Shutdown a bus(, remove driver instances) and continue operation. 
        We have no good idea currently.
        Does someone have a idea?

Thanks,
Hironobu Ishii


^ permalink raw reply

* [RFC/PATCH, 1/4] readX_check() performance evaluation
From: Hironobu Ishii @ 2004-01-28  1:54 UTC (permalink / raw)
  To: linux-kernel, linux-ia64

Hi all,

We are planning recovery from the PCI bus intermittent errors.
PCI-X standard describes it as "5.4 Error Handling and Fault
Tolerance" in PCI-X 1.0b.  There were several discussions in lkml,
how to recover from PCI errors.

Seto posted "[RFC] How drivers notice a HW error?" (readX_check() I/F)
   http://marc.theaimsgroup.com/?l=linux-kernel&m=106992207709400&w=2

Grant will show his idea near future,
   http://marc.theaimsgroup.com/?l=linux-kernel&m=107453681120603&w=2

I made a readX_check() prototype which Seto proposed to measure
performance disadvantage of this kind of I/F. And I made a performance
evaluation of Disk I/O with this prototype.
Comments are welcome.


Conclusion:
    Performance disadvantage of readX_check() is a very small.
    I'd like you to understand that such a function will not 
    cause severe performance disadvantage as you imagine.

This patch:
     - is for Fusion MPT driver.
     - has no error recovery code yet, sorry.
     - currently supports ia64 only. But I believe that
       some other CPU(such as SPARC, PPC, PA-RISC) can also
       support this kind of I/F. 
       I know, unfortunately, that i386 can't support this kind
       of I/F, because it can't recover from machine check state.

How to use this patch:
        - Apply to vanilla 2.6.1.
        - Rename drivers/message/fusion/mptbase.c to mptbase_main.c
          (Because we make mptbase.ko from mptbase.c and read_check.S,
          so source file name has to be renamed.  Though I know
          read_check.S should go under the architecture directory,
          because this patch is only for performance evaluation,
          forgive me. )

Evaluation Environment:
    Kernel:
        vanilla 2.6.1 and  2.6.1+readX_check patch
    Platform:   Intel Tiger-4 (1-CPU)
        processor  : 0
        vendor     : GenuineIntel
        arch       : IA-64
        family     : Itanium 2
        model      : 1
        revision   : 5
        archrev    : 0
        features   : branchlong
        cpu number : 0
        cpu regs   : 4
        cpu MHz    : 1296.473997
        itc MHz    : 1296.473997
        BogoMIPS   : 1941.96
    SCSI HBA/driver:
        onboard LSI Logic 53C1030(FwRev=01030600h, MaxQ=255)
        Fusion MPT driver(kernel 2.6.1)
    Disks
        Host: scsi0 Channel: 00 Id: 00 Lun: 00
          Vendor: FUJITSU  Model: MAP3367NC        Rev: 5207
          Type:   Direct-Access                    ANSI SCSI revision: 03
        Host: scsi0 Channel: 00 Id: 01 Lun: 00
          Vendor: FUJITSU  Model: MAP3367NC        Rev: 5207
          Type:   Direct-Access                    ANSI SCSI revision: 03
        Host: scsi0 Channel: 00 Id: 02 Lun: 00
          Vendor: FUJITSU  Model: MAP3367NC        Rev: 5207
          Type:   Direct-Access                    ANSI SCSI revision: 03

    Test tool:
        rawread 1.0.3
        http://www-124.ibm.com/developerworks/opensource/linuxperf/rawread/rawread.html

Results:
    To avoid buffer cache, we measured performance by O_DIRECT.

1-1) ./rawread -p 1 -d 1 -s 512 -n 131072 -x -z
     (1 disk, 512-bytes/1-read,)
                                        avg. sys(%) 
                    MB/s        IOPS    of vmstat
---------------------------------------------------
patched 2.6.1       5.245       10741   16.2
vanilla 2.6.1       5.269       10790   15.7
---------------------------------------------------
patched/vanilla     0.995               1.032

1-2) ./rawread -p 2 -d 1 -s 512 -n 131072 -x -z
     (2 disks, 512-bytes/1-read,)
                                        avg. sys(%) 
                    MB/s        IOPS    of vmstat
---------------------------------------------------
patched 2.6.1       10.473      21448   30.6
vanilla 2.6.1       10.548      21602   30.6
---------------------------------------------------
patched/vanilla     0.993               1.000


1-3) ./rawread -p 3 -d 1 -s 512 -n 131072 -x -z
     (3 disks, 512-bytes/1-read,)
                                        avg. sys(%) 
                    MB/s        IOPS    of vmstat
---------------------------------------------------
patched 2.6.1      11.267       23074   29.9
vanilla 2.6.1      11.251       23042   30.5
---------------------------------------------------
patched/vanilla     1.001               0.980


2-1) ./rawread -p 1 -d 1 -s 4096 -n 131072 -x -z
     (1 disk, 4096-bytes/1-read,)
                                        avg. sys(%) 
                    MB/s        IOPS    of vmstat
---------------------------------------------------
patched 2.6.1      39.422       10092   14.1
vanilla 2.6.1      39.389       10083   14.0
---------------------------------------------------
patched/vanilla    1.001                1.007
   
2-2) ./rawread -p 2 -d 1 -s 4096 -n 131072 -x -z
     (2 disks, 4096-bytes/1-read,)
                                        avg. sys(%) 
                    MB/s        IOPS    of vmstat
---------------------------------------------------
patched 2.6.1      70.438       18032   24.1
vanilla 2.6.1      70.390       18019   24.1
---------------------------------------------------
patched/vanilla    1.001                1.000


2-3) ./rawread -p 3 -d 1 -s 4096 -n 131072 -x -z
     (3 disks, 4096-bytes/1-read,)
                                        avg. sys(%) 
                    MB/s        IOPS    of vmstat
---------------------------------------------------
patched 2.6.1      70.588       18070   24.5
vanilla 2.6.1      70.861       18140   24.4
---------------------------------------------------
patched/vanilla    0.996                1.004

3-1) ./rawread -p 1 -d 1 -s 32768 -n 131072 -x -z
     (1 disk, 32768-bytes/1-read,)
                                        avg. sys(%) 
                    MB/s        IOPS    of vmstat
---------------------------------------------------
patched 2.6.1      69.226       2215     3.5
vanilla 2.6.1      68.546       2190     3.4
---------------------------------------------------
patched/vanilla    1.010                1.029

   
3-2) ./rawread -p 2 -d 1 -s 32768 -n 131072 -x -z
     (2 disk, 32768-bytes/1-read,)
                                        avg. sys(%) 
                    MB/s        IOPS    of vmstat
---------------------------------------------------
patched 2.6.1     139.315       4458     7.0
vanilla 2.6.1     139.188       4454     6.6
---------------------------------------------------
patched/vanilla    1.010                1.029

3-3) ./rawread -p 3 -d 1 -s 32768 -n 131072 -x -z
     (3 disks, 32768-bytes/1-read,)
                                        avg. sys(%) 
                    MB/s        IOPS    of vmstat
---------------------------------------------------
patched 2.6.1     208.883       6684    10.0
vanilla 2.6.1     209.193       6694    10.2
---------------------------------------------------
patched/vanilla    0.999                0.980

-------
Thanks,
Hironobu Ishii


^ permalink raw reply

* Undeliverable: Uzndyhugsblzzk
From: System Administrator @ 2004-01-28  1:55 UTC (permalink / raw)
  To: acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

[-- Attachment #1: Type: text/plain, Size: 472 bytes --]

Your message

  To:      adam-lkUOi89bZVhZroRs9YW3xA@public.gmane.org
  Subject: Uzndyhugsblzzk
  Sent:    Tue, 27 Jan 2004 17:55:22 -0800

did not reach the following recipient(s):

ADAM-QhW/2Vom2tPCiEU5iHfedg@public.gmane.org on Tue, 27 Jan 2004 17:55:29 -0800
    The recipient name is not recognized
	The MTS-ID of the original message is: c=us;a=
;p=wonderware;l=WWGATEWAY0401280155DXS21XBC
    MSEXCH:IMS:wonderware:irvine:WWGATEWAY 0 (000C05A6) Unknown Recipient



[-- Attachment #2: Type: message/rfc822, Size: 1234 bytes --]

[-- Attachment #2.1.1: Type: text/plain, Size: 84 bytes --]

The message contains Unicode characters and has been sent as a binary
attachment.



[-- Attachment #2.1.2: WARNING0.txt --]
[-- Type: text/plain, Size: 282 bytes --]

McAfee WebShield SMTP 4.5 MR1a P0803.345 on mail2 at wonderware.com detected
W32/Mydoom-TkFRTFPJOQk@public.gmane.org (ED) in attachment file.zip from <acpi-devel@lists.sourceforge.net> intended
for <adam-lkUOi89bZVhZroRs9YW3xA@public.gmane.org>  and it was Deleted and Quarantined.

[-- Attachment #2.1.3: ATT43490.ATT --]
[-- Type: text/plain, Size: 0 bytes --]



^ permalink raw reply

* [RFC/PATCH, 4/4] readX_check() performance evaluation
From: Hironobu Ishii @ 2004-01-28  1:54 UTC (permalink / raw)
  To: linux-kernel, linux-ia64

This is our goal and plan.

Our goal:
    - We'd like to recover from PCI-X intermittent errors
      as possible as we can.
      We'd like to recvoer from following errors
         a) PIO read data parity errors
         b) PIO write data parity erros
         c) DMA read data parity errors
         d) DMA write data parity erros
      (PIO means that the initiator is the CPU,
      DMA means that the initiator is the device.)
    - If a fatal bus error like SERR occurs, we'd like to shutdown 
      the failed bus(, remove driver instances) and continue 
      system operation.
    - If there are readX_check() I/F, we can safely perform 
      PHP(PCI Hotplug) operation.
      Currently there is no reliable I/F to check the newly 
      installed card, so to speak, PHP is the same as the gambling.

Our Plan:
    - Recover from Data parity error
        Currently, we are focused on ia64 architecture.

        Device setup assumption:
          PCI command register/ Parity error response =1
          PCI-X command register/ Data parity error recovery=1

        a) PIO read data parity error recovery
          (Memory mapped I/O read error recovery)

          - readX_check() read the memory mapped hardware
            and consume the data by additional instruction.
          - If there were data parity error, machine check will
            occurs.  Local machine check handler check whether 
            the exception was caused by readX_check() 
            and increment a per-CPU MCA counter variable.
            Then handler returns.
          - readX_check check the per-CPU MCA counter variable.
            When the counter is incremented, return an error.
          - If readX_check() returns an error and if reading 
            the register has no side-effect, re-read the register
            a few times to recover from the error.
            If reading the register has a side-effect, driver may
            reset the HW and restart operation.

        b) PIO write data parity error recovery
          (Memory mapped I/O write error recovery)
          
          - The device will find a parity error.
            When the device find a parity error, 
            it reports the error in the PCI status 
            register as "Detected Parity Error = 1".
            After the driver did some PIO writes,
            the driver can notice the error by reading
            the PCI staus register.
          - If writing to the register has no side-effect,
            the driver can re-writeto the register.
            If writing the register has a side-effect,
            driver may reset the HW and restart operation.

        c) DMA read data parity errors
           (DMA from memory to device)

          - The device will find a parity error.
            When the device detected a data parity error,
            it set the "Detected Parity Error = 1".

            After a while, the driver check the PCI status
            register, and knows that there was a data parity error.
          - Because the driver can't decide which I/O failed
            precisely, the recovery method will be reseting the HW
            and restarting the I/O if possible.

        d) DMA write data parity erros
           (DMA from device to memory)

           - Host bridge detect the data parity error,
             and assert PERR signal on the bus.
             Then the device will notice the error and 
             report it in PCI status register as 
             "Master Data Parity error = 1".
          - Because the driver can't decide which I/O failed
            precisely, the recovery method will be reseting the HW
            and restarting the I/O if possible.

    - Shutdown a bus(, remove driver instances) and continue operation. 
        We have no good idea currently.
        Does someone have a idea?

Thanks,
Hironobu Ishii


^ permalink raw reply

* [RFC/PATCH, 3/4] readX_check() performance evaluation
From: Hironobu Ishii @ 2004-01-28  1:54 UTC (permalink / raw)
  To: linux-kernel, linux-ia64

This is a patch for rawread 1.0.3.
Original rawread 1.0.3 depends on i386.

Thanks, 
Hironobu Ishii

--- rawread.c.old 2004-01-22 19:33:43.000000000 +0900
+++ rawread.c 2004-01-27 23:26:24.406717936 +0900
@@ -94,8 +94,14 @@
 
 __inline__ unsigned long long int rdtsc()
 {
-  unsigned long long int x;
-  __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
+ unsigned long long int x;
+#if __i386__
+ __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
+#elif __ia64__
+ __asm__ volatile ("mov r8 = ar44");
+#else
+ #error "Please write your own rdtsc()"
+#endif
   return x;
 }
 


^ permalink raw reply

* [RFC/PATCH, 2/4] readX_check() performance evaluation
From: Hironobu Ishii @ 2004-01-28  1:54 UTC (permalink / raw)
  To: linux-kernel, linux-ia64

This is a readX_check() prototype patch to evaluate
the performance disadvantage.

Thanks,
Hironobu Ishii
--------------------
diff -prN linux-2.6.1/drivers/message/fusion/Makefile linux-2.6.1.modified/drivers/message/fusion/Makefile
*** linux-2.6.1/drivers/message/fusion/Makefile 2004-01-09 15:59:45.000000000 +0900
--- linux-2.6.1.modified/drivers/message/fusion/Makefile 2004-01-26 20:25:21.691512363 +0900
***************
*** 15,20 ****
--- 15,23 ----
  
  EXTRA_CFLAGS += ${MPT_CFLAGS}
  
+ # for PCI_RECOVERY
+ EXTRA_CFLAGS += -DCONFIG_PCI_RECOVERY
+ 
  # Fusion MPT drivers; recognized debug defines...
  #  MPT general:
  #EXTRA_CFLAGS += -DDEBUG
*************** obj-$(CONFIG_FUSION)  += mptbase.o mptsc
*** 50,52 ****
--- 53,60 ----
  obj-$(CONFIG_FUSION_ISENSE) += isense.o
  obj-$(CONFIG_FUSION_CTL) += mptctl.o
  obj-$(CONFIG_FUSION_LAN) += mptlan.o
+ 
+ # for PCI error recovery
+ mptbase-objs := mptbase_main.o read_check.o
+ 
+ 
diff -prN linux-2.6.1/drivers/message/fusion/mptbase.c linux-2.6.1.modified/drivers/message/fusion/mptbase.c
*** linux-2.6.1/drivers/message/fusion/mptbase.c 2004-01-09 15:59:18.000000000 +0900
--- linux-2.6.1.modified/drivers/message/fusion/mptbase.c 2004-01-26 22:29:18.185561891 +0900
*************** struct _mpt_ioc_proc_list {
*** 260,265 ****
--- 260,305 ----
  
  #endif
  
+ 
+ #ifdef CONFIG_PCI_RECOVERY
+ /*
+  * Try to recover from PCI intermittent read errors
+  */
+ #define REG_READ_SUCCESS   0
+ 
+ #define REG_READ_OK        0
+ #define REG_READ_RETRY_OK  1
+ #define REG_READ_NG       -1
+ 
+ #define REG_READ_RETRY     5 /* retry limit */
+ 
+ extern inline int readl_check(volatile u32 *d, volatile u32 *a);
+ 
+ static inline int do_readl(volatile u32 *d, volatile u32 *a)
+ {
+  int  retry ;
+  int  fail = 0;
+ 
+  for (retry = REG_READ_RETRY; retry; retry--) {
+   if (readl_check(d, a) = REG_READ_SUCCESS) {
+    return (fail ? REG_READ_RETRY_OK : REG_READ_OK);
+   }
+   fail++;
+  }
+  /* retry out */
+  /* PCI reset? */
+  return REG_READ_NG;
+ }
+ 
+ static inline int CHIPREG_READ32(volatile u32 *d, volatile u32 *a)
+ {
+  if (PortIo) {
+   *d =inl((unsigned long)a);
+   return REG_READ_OK;
+  } else
+   return do_readl(d, a);
+ }
+ #else
  /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  /* 20000207 -sralston
   *  GRRRRR...  IOSpace (port i/o) register access (for the 909) is back!
*************** static inline u32 CHIPREG_READ32(volatil
*** 274,279 ****
--- 314,320 ----
   else
    return readl(a);
  }
+ #endif
  
  static inline void CHIPREG_WRITE32(volatile u32 *a, u32 v)
  {
*************** mpt_interrupt(int irq, void *bus_id, str
*** 352,360 ****
    */
   while (1) {
  
    if ((pa = CHIPREG_READ32(&ioc->chip->ReplyFifo)) = 0xFFFFFFFF)
     return IRQ_HANDLED;
! 
    cb_idx = 0;
    freeme = 0;
  
--- 393,413 ----
    */
   while (1) {
  
+ #ifdef CONFIG_PCI_RECOVERY
+   {
+    int read_fail;
+    read_fail = CHIPREG_READ32(&pa, &ioc->chip->ReplyFifo);
+    if (read_fail) {
+     printk("PCI PIO read error:%d\n", read_fail);
+     /* recovery code */
+    }
+    if (pa = 0xFFFFFFFF)
+     return IRQ_HANDLED;
+   }
+ #else
    if ((pa = CHIPREG_READ32(&ioc->chip->ReplyFifo)) = 0xFFFFFFFF)
     return IRQ_HANDLED;
! #endif
    cb_idx = 0;
    freeme = 0;
  
*************** mpt_send_handshake_request(int handle, i
*** 1066,1073 ****
--- 1119,1140 ----
    }
  
    /* Read doorbell and check for active bit */
+ #ifdef CONFIG_PCI_RECOVERY
+   {
+      int read_fail;
+      u32 dummy;
+      read_fail = CHIPREG_READ32(&dummy, &iocp->chip->Doorbell);
+      if (read_fail) {
+       printk("PCI PIO read error:%d\n", read_fail);
+       /* recovery code */
+      }
+      if (!(dummy & MPI_DOORBELL_ACTIVE))
+       return -5;
+   }
+ #else
    if (!(CHIPREG_READ32(&iocp->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
      return -5;
+ #endif
  
    dhsprintk((KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
      iocp->name, ii));
*************** mpt_GetIocState(MPT_ADAPTER *ioc, int co
*** 2170,2176 ****
--- 2237,2255 ----
   u32 s, sc;
  
   /*  Get!  */
+ #ifdef CONFIG_PCI_RECOVERY
+  {
+   int read_fail;
+   read_fail = CHIPREG_READ32(&s, &ioc->chip->Doorbell);
+   if (read_fail) {
+    printk("PCI PIO read error:%d\n", read_fail);
+    /* recovery code */
+   }
+  }
+ #else
   s = CHIPREG_READ32(&ioc->chip->Doorbell);
+ #endif
+ 
  // dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
   sc = s & MPI_IOC_STATE_MASK;
  
*************** mpt_downloadboot(MPT_ADAPTER *ioc, int s
*** 2871,2879 ****
--- 2950,2981 ----
   ddlprintk((MYIOC_s_INFO_FMT "DbGb0: downloadboot entered.\n",
      ioc->name));
  #ifdef MPT_DEBUG
+ #ifdef CONFIG_PCI_RECOVERY
+  {
+   int read_fail ;
+   read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+   if (read_fail) {
+    printk("PCI PIO read error:%d\n", read_fail);
+    /* recovery codes */
+   }
+  }
+ #else
   diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif
+ 
+ #ifdef CONFIG_PCI_RECOVERY
+  if (ioc->alt_ioc) {
+   int read_fail ;
+   read_fail = CHIPREG_READ32(&diag1val, &ioc->alt_ioc->chip->Diagnostic);
+   if (read_fail) {
+    printk("PCI PIO read error:%d\n", read_fail);
+    /* recovery code */
+   }
+  }
+ #else
   if (ioc->alt_ioc)
    diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ #endif
   ddlprintk((MYIOC_s_INFO_FMT "DbGb1: diag0=%08x, diag1=%08x\n",
      ioc->name, diag0val, diag1val));
  #endif
*************** mpt_downloadboot(MPT_ADAPTER *ioc, int s
*** 2903,2909 ****
--- 3005,3023 ----
   /* Write magic sequence to WriteSequence register
    * until enter diagnostic mode
    */
+ #ifdef CONFIG_PCI_RECOVERY
+  {
+   int read_fail;
+   read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+   if (read_fail) {
+    printk("PCI PIO error:%d\n", read_fail);
+    /* recovery code */
+   }
+  }
+ #else
   diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif
+ 
   while ((diag0val & MPI_DIAG_DRWE) = 0) {
    CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
    CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
*************** mpt_downloadboot(MPT_ADAPTER *ioc, int s
*** 2928,2937 ****
--- 3042,3075 ----
  
    }
  
+ #ifdef CONFIG_PCI_RECOVERY
+   {
+    int read_fail ;
+    read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+    if (read_fail) {
+     printk("PCI PIO read error:%d\n", read_fail);
+     /* recovery code */
+    }
+   }
+ #else
    diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif
+ 
  #ifdef MPT_DEBUG
+ #ifdef CONFIG_PCI_RECOVERY
+   if (ioc->alt_ioc)  {
+    int read_fail;
+    read_fail = CHIPREG_READ32(&diag1val, &ioc->alt_ioc->chip->Diagnostic);
+    if (read_fail) {
+     printk("PCI PIO read error:%d\n", read_fail);
+     /* recovery code */
+    }
+   }
+ #else
    if (ioc->alt_ioc)
     diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ #endif
+ 
    ddlprintk((MYIOC_s_INFO_FMT "DbGb3: diag0=%08x, diag1=%08x\n",
      ioc->name, diag0val, diag1val));
  #endif
*************** mpt_downloadboot(MPT_ADAPTER *ioc, int s
*** 2944,2951 ****
--- 3082,3100 ----
   CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
  
  #ifdef MPT_DEBUG
+ #ifdef CONFIG_PCI_RECOVERY
+  if (ioc->alt_ioc) {
+   int read_fail;
+   read_fail = CHIPREG_READ32(&diag1val, &ioc->alt_ioc->chip->Diagnostic);
+   if (read_fail) {
+    printk("PCI PIO read error:%d\n", read_fail);
+    /* recovery code */
+   }
+  }
+ #else
   if (ioc->alt_ioc)
    diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ #endif
  
   ddlprintk((MYIOC_s_INFO_FMT "DbGb3: diag0=%08x, diag1=%08x\n",
     ioc->name, diag0val, diag1val));
*************** mpt_downloadboot(MPT_ADAPTER *ioc, int s
*** 3097,3103 ****
--- 3246,3265 ----
   CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
  
   /* clear the RW enable and DISARM bits */
+ #ifdef CONFIG_PCI_RECOVERY
+  {
+   int read_fail ;
+ 
+   read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+   if (read_fail) {
+    printk("PCI PIO read error:%d\n", read_fail);
+    /* recovery code */
+   }
+  }
+ #else
   diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif
+ 
   diag0val &= ~(MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE | MPI_DIAG_FLASH_BAD_SIG);
   CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
  
*************** mpt_diag_reset(MPT_ADAPTER *ioc, int ign
*** 3215,3225 ****
--- 3377,3410 ----
   CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
  
   /* Use "Diagnostic reset" method! (only thing available!) */
+ #ifdef CONFIG_PCI_RECOVERY
+  {
+   int read_fail;
+   read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+   if (read_fail) {
+    printk("PCI PIO read error:%d\n", read_fail);
+    /* recovery code */
+   }
+  }
+ #else
   diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif
  
  #ifdef MPT_DEBUG
+ #ifdef CONFIG_PCI_RECOVERY
+  if (ioc->alt_ioc) {
+   int read_fail;
+   read_fail = CHIPREG_READ32(&diag1val, &ioc->alt_ioc->chip->Diagnostic);
+   if (read_fail) {
+    printk("PCI PIO read error:%d\n", read_fail);
+    /* recovery code */
+   }
+  }
+ #else
   if (ioc->alt_ioc)
    diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ #endif
+ 
   dprintk((MYIOC_s_INFO_FMT "DbG1: diag0=%08x, diag1=%08x\n",
     ioc->name, diag0val, diag1val));
  #endif
*************** mpt_diag_reset(MPT_ADAPTER *ioc, int ign
*** 3255,3269 ****
--- 3440,3477 ----
  
     }
  
+ #ifdef CONFIG_PCI_RECOVERY
+    {
+     int read_fail;
+     read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+     if (read_fail) {
+      printk("PCI PIO read error:%d\n", read_fail);
+      /* recovery code */
+     }
+    }
+ #else
     diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif
  
     dprintk((MYIOC_s_INFO_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
       ioc->name, diag0val));
    }
  
  #ifdef MPT_DEBUG
+ #ifndef CONFIG_PCI_RECOVERY
+   if (ioc->alt_ioc) {
+    int read_fail;
+    read_fail = CHIPREG_READ32(&diag1val, &ioc->alt_ioc->chip->Diagnostic);
+    if (read_fail) {
+     printk("PCI PIO read error:%d\n", read_fail);
+     /* recovery code */
+    }
+   }
+ #else
    if (ioc->alt_ioc)
     diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ #endif
+ 
    dprintk((MYIOC_s_INFO_FMT "DbG2: diag0=%08x, diag1=%08x\n",
      ioc->name, diag0val, diag1val));
  #endif
*************** mpt_diag_reset(MPT_ADAPTER *ioc, int ign
*** 3320,3329 ****
--- 3528,3561 ----
      * case.  _diag_reset will return < 0
      */
     for (count = 0; count < 30; count ++) {
+ #ifdef CONFIG_PCI_RECOVERY
+     {
+      int read_fail;
+      read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+      if (read_fail) {
+       printk("PCI PIO read error:%d\n", read_fail);
+       /* recovery code */
+      }
+     }
+ #else
      diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif
+ 
  #ifdef MPT_DEBUG
+ #ifdef CONFIG_PCI_RECOVERY
+     if (ioc->alt_ioc) {
+      int read_fail;
+      read_fail = CHIPREG_READ32(&diag1val, &ioc->alt_ioc->chip->Diagnostic);
+      if (read_fail) {
+       printk("PCI PIO read error:%d\n", read_fail);
+       /* recovery code */
+      }
+     }
+ #else
      if (ioc->alt_ioc)
       diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ #endif
+ 
      dprintk((MYIOC_s_INFO_FMT
       "DbG2b: diag0=%08x, diag1=%08x\n",
       ioc->name, diag0val, diag1val));
*************** mpt_diag_reset(MPT_ADAPTER *ioc, int ign
*** 3353,3359 ****
--- 3585,3603 ----
      * with calling program.
      */
     for (count = 0; count < 30; count ++) {
+ #ifdef CONFIG_PCI_RECOVERY
+     {
+      int read_fail;
+      read_fail = CHIPREG_READ32(&doorbell, &ioc->chip->Doorbell);
+      if (read_fail) {
+       printk("PCI PIO read error:%d\n", read_fail);
+       /* recovery code */
+      }
+     }
+ #else
      doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
+ #endif
+ 
      doorbell &= MPI_IOC_STATE_MASK;
  
      if (doorbell = MPI_IOC_STATE_READY) {
*************** mpt_diag_reset(MPT_ADAPTER *ioc, int ign
*** 3371,3380 ****
--- 3615,3648 ----
    }
   }
  
+ #ifdef CONFIG_PCI_RECOVERY
+  {
+   int read_fail;
+   read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+   if (read_fail) {
+    printk("PCI PIO read error:%d\n", read_fail);
+    /* recovery code */
+   }
+  }
+ #else
   diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif
+ 
  #ifdef MPT_DEBUG
+ #ifdef CONFIG_PCI_RECOVERY
+  if (ioc->alt_ioc) {
+   int read_fail;
+   read_fail = CHIPREG_READ32(&diag1val, &ioc->alt_ioc->chip->Diagnostic);
+   if (read_fail) {
+    printk("PCI PIO read error:%d\n", read_fail);
+    /* recovery code */
+   }
+  }
+ #else
   if (ioc->alt_ioc)
    diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ #endif
+ 
   dprintk((MYIOC_s_INFO_FMT "DbG3: diag0=%08x, diag1=%08x\n",
    ioc->name, diag0val, diag1val));
  #endif
*************** mpt_diag_reset(MPT_ADAPTER *ioc, int ign
*** 3382,3388 ****
--- 3650,3668 ----
   /* Clear RESET_HISTORY bit!  Place board in the
    * diagnostic mode to update the diag register.
    */
+ #ifdef CONFIG_PCI_RECOVERY
+  {
+   int read_fail;
+   read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+   if (read_fail) {
+    printk("PCI PIO read error:%d\n", read_fail);
+    /* recovery code */
+   }
+  }
+ #else
   diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif
+ 
   count = 0;
   while ((diag0val & MPI_DIAG_DRWE) = 0) {
    /* Write magic sequence to WriteSequence register
*************** mpt_diag_reset(MPT_ADAPTER *ioc, int ign
*** 3408,3418 ****
--- 3688,3722 ----
       ioc->name, diag0val);
     break;
    }
+ #ifdef CONFIG_PCI_RECOVERY
+   {
+    int read_fail;
+    read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+    if (read_fail) {
+     printk("PCI PIO read error:%d\n", read_fail);
+     /* recovery code */
+    }
+   }
+ #else
    diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif
+ 
   }
   diag0val &= ~MPI_DIAG_RESET_HISTORY;
   CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
+ #ifdef CONFIG_PCI_RECOVERY
+  {
+   int read_fail;
+   read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+   if (read_fail) {
+    printk("PCI PIO read error:%d\n", read_fail);
+    /* recovery code */
+   }
+  }
+ #else
   diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif
+ 
   if (diag0val & MPI_DIAG_RESET_HISTORY) {
    printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
      ioc->name);
*************** mpt_diag_reset(MPT_ADAPTER *ioc, int ign
*** 3424,3430 ****
--- 3728,3746 ----
  
   /* Check FW reload status flags.
    */
+ #ifdef CONFIG_PCI_RECOVERY
+  {
+   int read_fail;
+   read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+   if (read_fail) {
+    printk("PCI PIO read error:%d\n", read_fail);
+    /* recovery code */
+   }
+  }
+ #else
   diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif
+ 
   if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
    printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
      ioc->name, diag0val);
*************** mpt_diag_reset(MPT_ADAPTER *ioc, int ign
*** 3432,3439 ****
--- 3748,3767 ----
   }
  
  #ifdef MPT_DEBUG
+ #ifdef CONFIG_PCI_RECOVERY
+  if (ioc->alt_ioc) {
+   int read_fail;
+   read_fail = CHIPREG_READ32(&diag1val, &ioc->chip->Diagnostic);
+   if (read_fail) {
+    printk("PCI PIO read error:%d\n", read_fail);
+    /* recovery code */
+   }
+  }
+ #else
   if (ioc->alt_ioc)
    diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ #endif
+ 
   dprintk((MYIOC_s_INFO_FMT "DbG4: diag0=%08x, diag1=%08x\n",
     ioc->name, diag0val, diag1val));
  #endif
*************** mpt_handshake_req_reply_wait(MPT_ADAPTER
*** 3743,3750 ****
--- 4071,4092 ----
     ioc->name, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
  
   /* Read doorbell and check for active bit */
+ #ifdef CONFIG_PCI_RECOVERY
+  {
+   int read_fail;
+   u32 dummy;
+   read_fail = CHIPREG_READ32(&dummy, &ioc->chip->Doorbell);
+   if (read_fail) {
+    printk("PCI PIO read error:%d\n", read_fail);
+    /* recovery code */
+   }
+   if (!(dummy & MPI_DOORBELL_ACTIVE))
+    return -1;
+  }
+ #else
   if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
     return -1;
+ #endif
  
   /*
    * Clear doorbell int (WRITE 0 to IntStatus reg),
*************** WaitForDoorbellAck(MPT_ADAPTER *ioc, int
*** 3822,3828 ****
--- 4164,4182 ----
  
   if (sleepFlag = CAN_SLEEP) {
    while (--cntdn) {
+ #ifdef CONFIG_PCI_RECOVERY
+    {
+     int read_fail;
+     read_fail = CHIPREG_READ32(&intstat, &ioc->chip->IntStatus);
+     if (read_fail) {
+      printk("PCI PIO read error:%d\n", read_fail);
+      /* recovery code */
+        }
+    }
+ #else
     intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
+ #endif
+ 
     if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
      break;
     set_current_state(TASK_INTERRUPTIBLE);
*************** WaitForDoorbellAck(MPT_ADAPTER *ioc, int
*** 3831,3837 ****
--- 4185,4203 ----
    }
   } else {
    while (--cntdn) {
+ #ifdef CONFIG_PCI_RECOVERY
+    {
+     int read_fail;
+     read_fail = CHIPREG_READ32(&intstat, &ioc->chip->IntStatus);
+     if (read_fail) {
+      printk("PCI PIO read error:%d\n", read_fail);
+      /* recovery code */
+     }
+    }
+ #else
     intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
+ #endif
+ 
     if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
      break;
     mdelay (1);
*************** WaitForDoorbellInt(MPT_ADAPTER *ioc, int
*** 3872,3878 ****
--- 4238,4256 ----
   cntdn = ((sleepFlag = CAN_SLEEP) ? HZ : 1000) * howlong;
   if (sleepFlag = CAN_SLEEP) {
    while (--cntdn) {
+ #ifdef CONFIG_PCI_RECOVERY
+    {
+     int read_fail;
+     read_fail = CHIPREG_READ32(&intstat, &ioc->chip->IntStatus);
+     if (read_fail) {
+      printk("PCI PIO read error:%d\n", read_fail);
+      /* recovery code */
+     }
+    }
+ #else
     intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
+ #endif
+ 
     if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
      break;
     set_current_state(TASK_INTERRUPTIBLE);
*************** WaitForDoorbellInt(MPT_ADAPTER *ioc, int
*** 3881,3887 ****
--- 4259,4277 ----
    }
   } else {
    while (--cntdn) {
+ #ifdef CONFIG_PCI_RECOVERY
+    {
+     int read_fail;
+     read_fail = CHIPREG_READ32(&intstat, &ioc->chip->IntStatus);
+     if (read_fail) {
+      printk("PCI PIO read error:%d\n", read_fail);
+      /* recovery code */
+     }
+    }
+ #else
     intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
+ #endif
+ 
     if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
      break;
     mdelay(1);
*************** WaitForDoorbellReply(MPT_ADAPTER *ioc, i
*** 3932,3943 ****
--- 4322,4361 ----
   if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
    failcnt++;
   } else {
+ #ifdef CONFIG_PCI_RECOVERY
+   {
+    int read_fail;
+    u32 dummy;
+    read_fail = CHIPREG_READ32(&dummy, &ioc->chip->Doorbell);
+    if (read_fail) {
+     printk("PCI PIO read error:%d\n", read_fail);
+     /* recovery code */
+    }
+    hs_reply[u16cnt++] = le16_to_cpu(dummy & 0x0000FFFF);
+   }
+ #else
    hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
+ #endif
+ 
    CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
    if ((t = WaitForDoorbellInt(ioc, 2, sleepFlag)) < 0)
     failcnt++;
    else {
+ #ifdef CONFIG_PCI_RECOVERY
+    {
+     int read_fail;
+     u32 dummy;
+     read_fail = CHIPREG_READ32(&dummy, &ioc->chip->Doorbell);
+     if (read_fail) {
+      printk("PCI PIO read error:%d\n", read_fail);
+      /* recovery code */
+     }
+     hs_reply[u16cnt++] = le16_to_cpu(dummy & 0x0000FFFF);
+    }
+ #else
     hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
+ #endif
+ 
     CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
    }
   }
*************** WaitForDoorbellReply(MPT_ADAPTER *ioc, i
*** 3953,3959 ****
--- 4371,4391 ----
   for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
    if ((t = WaitForDoorbellInt(ioc, 2, sleepFlag)) < 0)
     failcnt++;
+ #ifdef CONFIG_PCI_RECOVERY
+   {
+    int read_fail;
+    u32 dummy;
+    read_fail = CHIPREG_READ32(&dummy, &ioc->chip->Doorbell);
+    if (read_fail) {
+     printk("PCI PIO read error:%d\n", read_fail);
+     /* recovery code */
+    }
+    hword = le16_to_cpu(dummy & 0x0000FFFF);
+   }
+ #else
    hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
+ #endif
+ 
    /* don't overflow our IOC hs_reply[] buffer! */
    if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
     hs_reply[u16cnt] = hword;
*************** fusion_init(void)
*** 5896,5901 ****
--- 6328,6339 ----
   show_mptmod_ver(my_NAME, my_VERSION);
   printk(KERN_INFO COPYRIGHT "\n");
  
+ #ifdef CONFIG_PCI_RECOVERY
+         printk(KERN_INFO "Enable PCI PIO read error recovery\n");
+ #else
+         printk(KERN_INFO "Disable PCI PIO read error recovery\n");
+ #endif
+ 
   Q_INIT(&MptAdapters, MPT_ADAPTER);   /* set to empty */
   for (i = 0; i < MPT_MAX_PROTOCOL_DRIVERS; i++) {
    MptCallbacks[i] = NULL;
*************** fusion_exit(void)
*** 5962,5968 ****
--- 6400,6418 ----
    /* Clear any lingering interrupt */
    CHIPREG_WRITE32(&this->chip->IntStatus, 0);
  
+ #ifdef CONFIG_PCI_RECOVERY
+   {
+    int read_fail;
+    u32 dummy;
+    read_fail = CHIPREG_READ32(&dummy, &this->chip->IntStatus);
+    if (read_fail) {
+     printk("PCI PIO read error:%d\n", read_fail);
+     /* recovery code */
+    }
+   }
+ #else
    CHIPREG_READ32(&this->chip->IntStatus);
+ #endif
  
    Q_DEL_ITEM(this);
    mpt_adapter_dispose(this);
diff -prN linux-2.6.1/drivers/message/fusion/mptbase.h linux-2.6.1.modified/drivers/message/fusion/mptbase.h
*** linux-2.6.1/drivers/message/fusion/mptbase.h 2004-01-09 15:59:10.000000000 +0900
--- linux-2.6.1.modified/drivers/message/fusion/mptbase.h 2004-01-26 16:41:43.394801737 +0900
***************
*** 80,87 ****
  #define COPYRIGHT "Copyright (c) 1999-2003 " MODULEAUTHOR
  #endif
  
! #define MPT_LINUX_VERSION_COMMON "2.05.00.05"
! #define MPT_LINUX_PACKAGE_NAME  "@(#)mptlinux-2.05.00.05"
  #define WHAT_MAGIC_STRING  "@" "(" "#" ")"
  
  #define show_mptmod_ver(s,ver)  \
--- 80,87 ----
  #define COPYRIGHT "Copyright (c) 1999-2003 " MODULEAUTHOR
  #endif
  
! #define MPT_LINUX_VERSION_COMMON "2.05.00.05PCI"
! #define MPT_LINUX_PACKAGE_NAME  "@(#)mptlinux-2.05.00.05PCI"
  #define WHAT_MAGIC_STRING  "@" "(" "#" ")"
  
  #define show_mptmod_ver(s,ver)  \
diff -prN linux-2.6.1/drivers/message/fusion/read_check.S linux-2.6.1.modified/drivers/message/fusion/read_check.S
*** linux-2.6.1/drivers/message/fusion/read_check.S 1970-01-01 09:00:00.000000000 +0900
--- linux-2.6.1.modified/drivers/message/fusion/read_check.S 2004-01-26 22:19:20.426780151 +0900
***************
*** 0 ****
--- 1,69 ----
+ #define ENTRY(name) \
+  .align 32; \
+  .global name; \
+  .proc name; \
+ name:
+ #define END(name) \
+  .endp name
+  
+ /****************************************************************************/
+  .rodata
+  .align 8
+  .global readchk_addrs
+ readchk_addrs:
+  data8 .readl_start#
+  data8 .readl_end#
+ 
+  /* This should be per CPU data */
+  .global readl_mca#
+  .sbss
+  .align 4
+  .type readl_mca#,@object
+  .size readl_mca#,4
+ readl_mca:
+  .skip 4
+ /*
+  *
+  * int readl_check( __u32 *valp, __u32 *addr ) ;
+  *     in0,           in1
+  */
+  .text
+  .align 16
+ ENTRY(readl_check)
+  .prologue
+  .body
+ {.mmi addl r15 = @ltoffx(readl_mca#), r1
+  ;;
+  ld8.mov r14 = [r15], readl_mca#  /* r14 = &readl_mca */
+  nop.i 0
+  ;;
+ }
+ .readl_start:
+ {.mmi ld4.acq r15 = [r14]  /* r15 = readl_mca */
+  ld4 r33 = [r33]  /* r33 = *addr(r33) */
+  nop.i 0
+  ;;
+ }
+ {.mmi add r16 =1, r33  /* consume r33 */
+  nop.m 0
+  nop.i 0
+  ;;
+ }
+ .readl_end:
+ {.mmi ld4.acq r14 = [r14]  /* r14 = readl_mca */
+  ;;
+  cmp4.ne p6, p7 = r14, r15 /* old readl_mca = readl_mca? */
+  nop.i 0
+  ;;
+ }
+ {.mmi (p7) st4 [r32] = r33  /* if (old=new) *valp(r32) = r33 */
+  (p7) mov r8 = r0  /* if (old=new) ret = 0 */
+  nop.i 0
+ }
+ {.mmb (p6) addl r8 = 1, r0  /* if (old!=new) ret = 1 */
+  nop.m 0
+  br.ret.sptk.many rp
+  ;;
+ }
+ 
+ END(readl_check)


^ permalink raw reply

* [RFC/PATCH, 1/4] readX_check() performance evaluation
From: Hironobu Ishii @ 2004-01-28  1:54 UTC (permalink / raw)
  To: linux-kernel, linux-ia64

Hi all,

We are planning recovery from the PCI bus intermittent errors.
PCI-X standard describes it as "5.4 Error Handling and Fault
Tolerance" in PCI-X 1.0b.  There were several discussions in lkml,
how to recover from PCI errors.

Seto posted "[RFC] How drivers notice a HW error?" (readX_check() I/F)
   http://marc.theaimsgroup.com/?l=linux-kernel&m\x106992207709400&w=2

Grant will show his idea near future,
   http://marc.theaimsgroup.com/?l=linux-kernel&m\x107453681120603&w=2

I made a readX_check() prototype which Seto proposed to measure
performance disadvantage of this kind of I/F. And I made a performance
evaluation of Disk I/O with this prototype.
Comments are welcome.


Conclusion:
    Performance disadvantage of readX_check() is a very small.
    I'd like you to understand that such a function will not 
    cause severe performance disadvantage as you imagine.

This patch:
     - is for Fusion MPT driver.
     - has no error recovery code yet, sorry.
     - currently supports ia64 only. But I believe that
       some other CPU(such as SPARC, PPC, PA-RISC) can also
       support this kind of I/F. 
       I know, unfortunately, that i386 can't support this kind
       of I/F, because it can't recover from machine check state.

How to use this patch:
        - Apply to vanilla 2.6.1.
        - Rename drivers/message/fusion/mptbase.c to mptbase_main.c
          (Because we make mptbase.ko from mptbase.c and read_check.S,
          so source file name has to be renamed.  Though I know
          read_check.S should go under the architecture directory,
          because this patch is only for performance evaluation,
          forgive me. )

Evaluation Environment:
    Kernel:
        vanilla 2.6.1 and  2.6.1+readX_check patch
    Platform:   Intel Tiger-4 (1-CPU)
        processor  : 0
        vendor     : GenuineIntel
        arch       : IA-64
        family     : Itanium 2
        model      : 1
        revision   : 5
        archrev    : 0
        features   : branchlong
        cpu number : 0
        cpu regs   : 4
        cpu MHz    : 1296.473997
        itc MHz    : 1296.473997
        BogoMIPS   : 1941.96
    SCSI HBA/driver:
        onboard LSI Logic 53C1030(FwRev\x01030600h, MaxQ%5)
        Fusion MPT driver(kernel 2.6.1)
    Disks
        Host: scsi0 Channel: 00 Id: 00 Lun: 00
          Vendor: FUJITSU  Model: MAP3367NC        Rev: 5207
          Type:   Direct-Access                    ANSI SCSI revision: 03
        Host: scsi0 Channel: 00 Id: 01 Lun: 00
          Vendor: FUJITSU  Model: MAP3367NC        Rev: 5207
          Type:   Direct-Access                    ANSI SCSI revision: 03
        Host: scsi0 Channel: 00 Id: 02 Lun: 00
          Vendor: FUJITSU  Model: MAP3367NC        Rev: 5207
          Type:   Direct-Access                    ANSI SCSI revision: 03

    Test tool:
        rawread 1.0.3
        http://www-124.ibm.com/developerworks/opensource/linuxperf/rawread/rawread.html

Results:
    To avoid buffer cache, we measured performance by O_DIRECT.

1-1) ./rawread -p 1 -d 1 -s 512 -n 131072 -x -z
     (1 disk, 512-bytes/1-read,)
                                        avg. sys(%) 
                    MB/s        IOPS    of vmstat
---------------------------------------------------
patched 2.6.1       5.245       10741   16.2
vanilla 2.6.1       5.269       10790   15.7
---------------------------------------------------
patched/vanilla     0.995               1.032

1-2) ./rawread -p 2 -d 1 -s 512 -n 131072 -x -z
     (2 disks, 512-bytes/1-read,)
                                        avg. sys(%) 
                    MB/s        IOPS    of vmstat
---------------------------------------------------
patched 2.6.1       10.473      21448   30.6
vanilla 2.6.1       10.548      21602   30.6
---------------------------------------------------
patched/vanilla     0.993               1.000


1-3) ./rawread -p 3 -d 1 -s 512 -n 131072 -x -z
     (3 disks, 512-bytes/1-read,)
                                        avg. sys(%) 
                    MB/s        IOPS    of vmstat
---------------------------------------------------
patched 2.6.1      11.267       23074   29.9
vanilla 2.6.1      11.251       23042   30.5
---------------------------------------------------
patched/vanilla     1.001               0.980


2-1) ./rawread -p 1 -d 1 -s 4096 -n 131072 -x -z
     (1 disk, 4096-bytes/1-read,)
                                        avg. sys(%) 
                    MB/s        IOPS    of vmstat
---------------------------------------------------
patched 2.6.1      39.422       10092   14.1
vanilla 2.6.1      39.389       10083   14.0
---------------------------------------------------
patched/vanilla    1.001                1.007
   
2-2) ./rawread -p 2 -d 1 -s 4096 -n 131072 -x -z
     (2 disks, 4096-bytes/1-read,)
                                        avg. sys(%) 
                    MB/s        IOPS    of vmstat
---------------------------------------------------
patched 2.6.1      70.438       18032   24.1
vanilla 2.6.1      70.390       18019   24.1
---------------------------------------------------
patched/vanilla    1.001                1.000


2-3) ./rawread -p 3 -d 1 -s 4096 -n 131072 -x -z
     (3 disks, 4096-bytes/1-read,)
                                        avg. sys(%) 
                    MB/s        IOPS    of vmstat
---------------------------------------------------
patched 2.6.1      70.588       18070   24.5
vanilla 2.6.1      70.861       18140   24.4
---------------------------------------------------
patched/vanilla    0.996                1.004

3-1) ./rawread -p 1 -d 1 -s 32768 -n 131072 -x -z
     (1 disk, 32768-bytes/1-read,)
                                        avg. sys(%) 
                    MB/s        IOPS    of vmstat
---------------------------------------------------
patched 2.6.1      69.226       2215     3.5
vanilla 2.6.1      68.546       2190     3.4
---------------------------------------------------
patched/vanilla    1.010                1.029

   
3-2) ./rawread -p 2 -d 1 -s 32768 -n 131072 -x -z
     (2 disk, 32768-bytes/1-read,)
                                        avg. sys(%) 
                    MB/s        IOPS    of vmstat
---------------------------------------------------
patched 2.6.1     139.315       4458     7.0
vanilla 2.6.1     139.188       4454     6.6
---------------------------------------------------
patched/vanilla    1.010                1.029

3-3) ./rawread -p 3 -d 1 -s 32768 -n 131072 -x -z
     (3 disks, 32768-bytes/1-read,)
                                        avg. sys(%) 
                    MB/s        IOPS    of vmstat
---------------------------------------------------
patched 2.6.1     208.883       6684    10.0
vanilla 2.6.1     209.193       6694    10.2
---------------------------------------------------
patched/vanilla    0.999                0.980

-------
Thanks,
Hironobu Ishii


^ permalink raw reply

* Re: raid set limit of 27 disks
From: Neil Brown @ 2004-01-28  1:43 UTC (permalink / raw)
  To: Tomas Hodan; +Cc: linux-raid
In-Reply-To: <DD454AE0A9AA8442A0A4422E919E6C2B03F62F95@msgemeamb01.ads.autodesk.com>

On Monday January 26, tomas.hodan@discreet.com wrote:
> hi all,
> 
> how can I increase the 27 disks limit in one raid set ?

Not yet. 
The raid super-block only has room to list 27 component devices (it
wastes space badly).
2.6 has support for a new improved layout, but there is no user-space
support for this yet.

NeilBrown

^ permalink raw reply


This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.