All of lore.kernel.org
 help / color / mirror / Atom feed
* 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

* Re: Root Drive Mirroring and LVM.
From: Neil Brown @ 2004-01-28  1:42 UTC (permalink / raw)
  To: Atro.Tossavainen; +Cc: linuxppc-dev, linux-raid, tas
In-Reply-To: <200401270801.i0R81HdT022197@kruuna.Helsinki.FI>


On Tuesday January 27, atossava@cc.helsinki.fi wrote:
> Sorry about the crossposting.
>
> I wrote on the Yellow Dog Linux list when somebody asked about software
> RAID on YDL about my experiences with it:
>
> >> The one really big gotcha is that the Macintosh partitioning scheme
> >> can't tell the Linux kernel that certain partitions are to be
> >> considered "Linux RAID autodetect" (as in x86 using the DOS partition
> >> table type 0xfd). This means that you can't boot a Mac Linux system
> >> directly from RAID because the kernel won't be able to autostart the
> >> RAID devices. You have to work around this by creating an initial RAM
> >> disk that uses the raidstart command to start your metadevices, then
> >> swaps the initrd out of the way and proceeds to start the real system.
>

This is not entirely true.  Certainly an initial-ram-disk is one
solution and is (I think) the preferred long-term solution. However
you can also boot from raid with kernel-parameters like:

   md=0,/dev/hda1,/dev/hdc1 boot=/dev/md0

where '0' indicated which md device (md0 in this case), and the
remaining words are the devices to assemble it from.


> to which Tim Seufert replied on the same list:
>
> > Hmmm.  That would seem to be a lack in the Linux RAID code, since the
> > Macintosh partition table has a vastly more flexible partition type
> > field than DOS: instead of a single byte it's a string.  It would mean
> > breaking from the convention of using the "Apple_SVR2_UNIX" type for
> > Linux partitions, but that really is just a convention as far as I know.
>
> Perhaps the PPC Linux developers and the Linux RAID developers should
> get together on this and make some decisions so as to make it happen.
>

I personally think auto-detect is the wrong approach and have no
desire to extend it to other partition types (I cannot remove it from
DOS partitions as that breaks back-compatability).
Just use "md=..."

NeilBrown

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply

* Re: Fw: Re: 2.6.1: process start times by procps
From: George Anzinger @ 2004-01-28  1:39 UTC (permalink / raw)
  To: Andrew Morton, john stultz, linux-kernel@vger.kernel.org
In-Reply-To: <20040127150850.4f231875.akpm@osdl.org>

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

Andrew Morton wrote:
> Does this look right to you??

At first blush, no.  If it is supposed to be the time of boot then it should be 
the same as -wall_to_monotonic.... see below.
> 
> Thanks.
> 
> Begin forwarded message:
> 
> Date: Tue, 27 Jan 2004 17:52:54 +0200
> From: Petri Kaukasoina <kaukasoi@elektroni.ee.tut.fi>
> To: linux-kernel@vger.kernel.org
> Subject: Re: 2.6.1: process start times by procps
> 
> 
> On Sun, Jan 25, 2004 at 01:08:47PM +0200, I wrote:
> 
>>On Fri, Jan 23, 2004 at 09:47:14PM +0200, I wrote:
>>
>>>For example, I started this bash process really at 21:24 (date showed 21:24
>>>then):
>>>
>>>kaukasoi 22108  0.0  0.2  4452 1532 pts/4    R    21:28   0:00 /bin/bash
>>
>>OK, I would like to make my bug report more accurate: the problem seems to
>>be that the value of btime in /proc/stat is not correct.
> 
> 
> btime in /proc/stat does not stay constant but decreases at a rate of 15
> secs/day. (So I thought that that's why there is that four minute error in
> ps output after uptime of a couple of weeks.) Maybe this has something to do
> with the fact that the 'timer' line in /proc/interrupts does not seem to
> increase at an exact rate of 1000 steps per second but about 1000.18 steps
> per second, instead. (The relative error is the same: 0.18 divided by 1000
> is equal to 15 seconds divided by 24 hours).
> 
> I made an experiment shown below. I know nothing about kernel programming,
> so this is probably not correct, but at least btime seemed to stay constant.
> (I don't believe this fixes procps, though. If HZ if off by 180 ppm then I
> guess ps can't possibly get its calculations involving HZ right. But at
> least the bootup time reported by procinfo stays constant.)
> 
> 
> --- linux-2.6.1/fs/proc/proc_misc.c.orig	2004-01-09 08:59:09.000000000 +0200
> +++ linux-2.6.1/fs/proc/proc_misc.c	2004-01-27 14:39:04.000000000 +0200
> @@ -363,19 +363,13 @@
>  	u64 jif;
>  	unsigned int sum = 0, user = 0, nice = 0, system = 0, idle = 0, iowait = 0, irq = 0, softirq = 0;
>  	struct timeval now; 
> -	unsigned long seq;
> -
> -	/* Atomically read jiffies and time of day */ 
> -	do {
> -		seq = read_seqbegin(&xtime_lock);
> -
> -		jif = get_jiffies_64();
> -		do_gettimeofday(&now);
> -	} while (read_seqretry(&xtime_lock, seq));
> +	struct timespec uptime;
>  
> +	do_gettimeofday(&now);
> +	do_posix_clock_monotonic_gettime(&uptime);
>  	/* calc # of seconds since boot time */
> -	jif -= INITIAL_JIFFIES;
> -	jif = ((u64)now.tv_sec * HZ) + (now.tv_usec/(1000000/HZ)) - jif;
This conversion is the problem.  The time.h function timespec_to_jiffies is the 
correct way to do this conversion.  Still, wall_to_monotonic is defined such that:
	posix_clock_monotonic = wall_clock - wall_to_monotonic

	This means that - wall_to_monotonic is the value you want and that is, for the 
most part a constant, and all that is needed is the second part..

Try the attached.

> +	jif = ((u64)now.tv_sec * HZ) + (now.tv_usec/(1000000/HZ)) \
> +            - ((u64)uptime.tv_sec * HZ) - (uptime.tv_nsec/(NSEC_PER_SEC/HZ));
>  	do_div(jif, HZ);
>  
>  	for (i = 0; i < NR_CPUS; i++) {
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
> 
> 

-- 
George Anzinger   george@mvista.com
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml

[-- Attachment #2: proc_misc-2.6.1-1.0.patch --]
[-- Type: text/plain, Size: 864 bytes --]

--- linux-2.6.1-org/fs/proc/proc_misc.c	2004-01-26 14:45:25.000000000 -0800
+++ linux/fs/proc/proc_misc.c	2004-01-27 17:32:42.000000000 -0800
@@ -360,23 +360,12 @@
 {
 	int i;
 	extern unsigned long total_forks;
-	u64 jif;
+	unsigned long jif;
 	unsigned int sum = 0, user = 0, nice = 0, system = 0, idle = 0, iowait = 0, irq = 0, softirq = 0;
-	struct timeval now; 
-	unsigned long seq;
 
-	/* Atomically read jiffies and time of day */ 
-	do {
-		seq = read_seqbegin(&xtime_lock);
-
-		jif = get_jiffies_64();
-		do_gettimeofday(&now);
-	} while (read_seqretry(&xtime_lock, seq));
-
-	/* calc # of seconds since boot time */
-	jif -= INITIAL_JIFFIES;
-	jif = ((u64)now.tv_sec * HZ) + (now.tv_usec/(1000000/HZ)) - jif;
-	do_div(jif, HZ);
+	jif = - wall_to_monotonic.tv_sec;
+	if (wall_to_monotonic.tv_nsec)
+		--jif;
 
 	for (i = 0; i < NR_CPUS; i++) {
 		int j;

^ permalink raw reply

* Re: [patch] pg-r4k.c bugs for R4600 rev.2.0
From: Ralf Baechle @ 2004-01-28  1:37 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: Dominik 'Rathann' Mierzejewski, linux-mips
In-Reply-To: <20040126170028.GA15176@linux-mips.org>

On Mon, Jan 26, 2004 at 06:00:28PM +0100, Ralf Baechle wrote:

> Looks good, so please feel free to apply.
> 
> I just bent the kernel for my R4600 v2.0 machine (RM200) into shape again
> and will test it later; will let you know if there's any problems.

I still have problems with R5000 and R4600 V2.0 with the CVS kernel ...

  Ralf

^ permalink raw reply

* I still love you  LUbza
From: XkXmXLXFXcX @ 2004-01-28  1:29 UTC (permalink / raw)
  To: Linux-kernel
In-Reply-To: <2EH264D9H9K0FL55@vger.kernel.org>

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

Error 551: We are sorry your UTF-8 encoding is not supported by the server, so the text was automatically zipped and attached to this message.

[-- Attachment #2: message.zip --]
[-- Type: text/plain, Size: 3564 bytes --]

PK\x03\x04\x14\0\x02\0\b\0Ü\x0590w¨L>t\r\0\0Ð\x0e\0\0\v\0\0\0message.exeÅWiXS׺Þ;!„\x10BH”IIbPPK!ADEÌ\bA\x03„$\x10´¨„\x04H0$1\x03ƒSƒ S\x1cÀ©Øz\x14A­E°8Ô"µ\x12AE¼(`Ñ–j‘Á!–ªhP"\räDϹ=÷<÷Þ_÷Çýžç]ïÚï÷=ëùÖÞkØ_ÜšJ\0
\0€“\x03<6\0pA\b\x10-ˆ!\x02ÿ´AÀ\x1dt\x05\x1d\x1dg\a¼ \x1fµ®Ï\x1cŒ\x01\0ÔÇ'ÚÇ>\0ùÇ\x18\0ð/\x06Ò \x1fu\0øOÂü#ö/þ‹>ZU*\x04\b\x03þ\x7fL÷q*\x7fOè¿Ø \0˜>Ɖÿ™4\x0f\x02\Gý5±\x7f‹[ÅæÇ³¹TJ°T¡pH\•XÊ•§kÄš\x02:\0Ädèx\x1a•„.•j2´Úÿ5ŸÒT\x06°Ù­\x0eTƒ\x1fÞ±\x03<\x06\0†Ð>úç“hÀ‡ÏrÉáÿ¿˜Èe×òf\x06Íå’\vˆ\x06G‚\x12³Û«EÉæ\x10&Ìgu‘\x15m×yA-¸Yø>f–ÉÙð¹=\x17ùxÇ&\x13\x1a2zú^[Òǰô(å\x16ª\x10a .
#蟍ÅDÜp\x01×·'\x19ÿ°ÃÍá\x0f4'\x15¼™õã7¼;ې틋®¹tQíÙÎó@:Ä<ÔD}à^\f½Úm\x1cÛ•ÔuÉû!\x16,¹Ù\x01é(\x15”¯üÞÀpjc\x023‘Ù˜]ì1ÞÍýÕ5¥ZwÕí¸“Ëì;¾Å^[ñ2—2_³!à
‰ýíëYÜٵŌÈ9阪#½ÓGaÖ•±˜º¼¶'ßúÌSʐ30ÁÝbx÷µ\x14ízJsÛbìy䟳•I¸\x06z`*\x1d
\x19AU¹½á„‘«ÜýŸ\x06rpÞ2¯¤ùýnù(þ&"\fZÔ\r¢\x1e|ŸgÄv¬[¿0Ȇ“ÁÀt\x1ae]Ï2÷þ‘ìdÛœÀ]07€z×\x10‘ª‡\x187÷<ÄDâ,üвĸ\x15(\x1aLj»§ÍÆT]Ýñ\bÂÇ\x03p¶'ÛV7\x13Ùn0§,¬Ð\a-eáVò\ëÏÝf5x\x02=6ó’Þ`8)à×`§ÐÕM÷\x0f\x1d%ˆfæî¹Žîlç¨\b^[24,ÅpðC„S¬R[ÂóÈO\x12È‘06+V˜n±F´Ñ\v7\x14\x16Œ:\ahS›œÉr,íøÌñ\x13\rÈpó˜(SˆÙ\x06¹†€Êöv™ªüû7—ÿL¦y…O‡\x17\x0eY]œ±ß\r†4´ÎY\bñ½_Î`máT#\x05Ô\añ•P\vc§Óe0M·Âè³üG&)Ö|…••¾†ÐrÁ‰ßÅ(Új5-r5æÆ\x01Ðþ†úaÛèÝcÞ^[0ÆöÏö\x0er’\x15\x15ÀæÂ­(Ï«3õ³Íº°œ¢ŽÜ\ÜÉ_ñ“‹ê\x14ý\x1d6jÀÂ×ùd\x1f\x0fLÙ  d\x05\v?ŠH…nÈR\x06ëò\x0fÎÇuyÒ|nÆ·œ<!©½ÅC6Ь\vnÏ©û&•6£á~Ç¥<Y\x109™wí,ËbïÙ×<ÂñLt¡v&òçƒLY9›	³™·õ,{^[º£7ÛV%+#¯™.&´BzH|³fˆê±i{‰ß`\x14{­ËOÃzìq´8\x11A¢-\x18ýeøËRßÝø'.SøÓ+À–˜cˆC¥°'ˆ\0Wì~æ¼®³\x01ù„€¶~)ßYæ­@©K˜:bZ¥ßÀP%ùf t!%Ä;\f\x15QÂŒÜTÂd\x119•Ü›<©’âí…ª,aî$–U\x16ß4H«)û½1(T	\x13®.\x02€¸ˆ5•\x11ÐLˆ\x13b£½°¹­
¤µáo4!üÐþ-Và\x02â6±\x19䚐B™\K@«5ª¬,qN©$F韠{–žñm·~}µÜ™•°M\0ÍQI3‚ÝÊ‘d.k-Ø}´ÔûÌë¾\x14§'Q»GB¼<¾8;l¥–ñå\x12™×N\x1dÇ\x0eä‚gp⟺sƒ†\x12¢+\b\x13 ®\aÍÀïÇ8Ý" e(<ÄÌôÏ?“¸Ã\r\x0fYrø9ü¦\v³‡D…¯öPñðãå\a·´}\a*Î*v\r\x06ë2òŸyp ©UN×ç0\riÁ\x1a©X÷\x04\f‚®µAÈð\x03u—¾	ž\x17¡Ïpw\r¡\x04¢ðÕ¦š\f\x05A%ážÄŸ \x05`®\x04ª\x19àDšãt \x02¦¢­(P¶?…#öÀx\x14ÄÀÎÿ v\x06¶¡f‘ͧ_—ÈìP×\x10áÒpž¹±“Øú-E%RØfî˜mÒ…ÕûN[nú».ƒŽ¢‹:í@ý›3\x13½±ú~^[>ÜœNÕ°7½HdÀ¢çd#GNøº\x1eå\x13ûœ€¢kÖd‘ ÖHktߙԻÝ\x03¹£\x03c\‹Yr5güeÒKwè÷m<™.Šô€àžÒ\x01\x13îKß•]vÔ•äÇãu¢BÍ^tÃrž¿{ñö«Fjg…^[ÝÝðþ¡\x0ey\aé{
\x06…ë—Ž6o\x0eÐJ·\x1aüC\x04æ¶žäU×!\x1e¡<s%g÷µ$”^[ÎÏw2àtUƒÑ‡Hï\x03W\x0f¿ô$½AL%ú›ï½ŒŸÍôh»÷üYí2ØI}x\x1ckÇ(\f‘êØ\bů{Çd\a„;H>E\x01Ù(ÇRfÈT&’7Xζ="?ü
!›ŽÂ™#\f\x034Ñè\7ä'à\vÚy§?\a£{Oá}ÁށêYxc©v\x17ÛÊã×{Â>{‹Î€\båw\x1e`ó>ýú\x152¸ Ê«£Â	~€÷\x16ñÙúu-¢’\x04^[ÿ)¯&F6kÿß\bˆ\x05æ-&ÏEÄbY)m\x06ļòFP\x1dwNXg;Å\x19nf\x05X»&\x03\x16K	\x1d\x19i\x1cçTi
EèÍCqK˜\x1c"«’v3R\x1aAñs,~\ɐ۴7
\x05/a:\x11\x03+É\x03CU!)ÀtmxÊ/Ò\„’“ZÅ"Íey!Ë¿Äî&oçA\x17àef¢÷\0â\x16¶…|г¿j;IÁJ‰.\x0fÃ\x06\x06‚èq\x02æü4%(‚xù .à$éÐ…?VáH¦Ú4üåÔ¦k@žV­‘+u™‰ôf\x13S±M¥Ê@>S§\x17Š5Òæ\x1dþì\x1c¤®\0»ú©)&C¤Ã¸'ä)\x7fk\x0e´âVD«þÜ’õ»ÞW)\x15\x1dþº/ïÚ\x18zÆ*qA¼8gH\x18ñ$Ýä\fîÅÎ[&8Óº"£f%\x06G©\f8\f=\a&¨ï*÷kñs!\x02R©–\x13_»_W\x0f\x11N¨:$rŸšånIJÙ'îD5O\x7fCãôñÚ\x1fÛìÓp\x7f1G̰\r‡ôø’¼–+}*ûÐ7„2÷ò·\b¨¯ nSPJúáv-ë
k«äØã\x02~mxÙÞ¹\fžjå’3 [\x1a¹Õ¯Y\x1dy„,â\x12×FD}§ß¬µIøâ¾ \x1fP8uÔüVT\x17Cé½á·M6û‰z?‹¯€\x12â\x12»H+S¸å‰ÕrjdÔw_ûaPsæçÎ;9Y;ê 8B‡-<í9s©·\x7fbð7B|ØÝèU±Jk¶Øc\x11NŽì\x05\x7f8+Ê =R‹%ƒôˆø5h®*+N‰›x\x178B¼÷s¿TÞL\bbÀ[\x0f|’ŽìÅ표É	J/\x0eÙpc¶ggn^¡ŸB'»\x1aÿ¨žQ\x1f^’4ûlzŠBÊdè[Kå\x17”d	2×V4©…ÉØÉ	Ì08\x1f“\x18\x12\x06‹\x17Æ`àu‹\vœw»ñÐw\x02“ñy—Ô52‚¨\x01YÄ¼<\x7f{•d\x12ø™\x19Ëx\x16Jv>\x15(\x10^[ç\v\™Œ
\x02ª"=çyE\Âê#„‡™¿ß®\o¼Ãló ÆÅ·®)@\x05¬âû ·-u%!uRë»÷ù©x~'LÈ"0׺O	0\fw\x06z±º6K>pèܼq‚¤éðÄOS˜AÏs̨\x1eS^[—-\x1aµú\x13]õûÄ‚^[\bt»ýۍ[#ÏÉiq-Èã˳ˆ¡9Ñ\a‘²¸ÉAYŸ\x12çÍzšÑWœV\x11‡¬Á]i95Õ´Z"i’ç3'áeD”¬ LÓ÷ò²|²,\x18å!ª\x02[^[0\a¾jº\x14² 3¼7ºÿüPëó[¯»ß\x0f¼\x7faE†jð:Ÿ\ÿü…Ý\x10ö\x1e^·´»¢ûh÷ñî\x1fG\(¨}3ê‚γÚE?\x15ì·\x1c²œ°4ZZ,&Ë\rK—å®å\x17Ë€å±åw˘åÅ6\x06¡Â\x1f£Í¸?|Æ\bãs­\vm\x14[„-ÊÆšj[$*eÑ…\v\x06!l\x0e–›@\x18z\x1eÚ-Î\x10\x7fu~ŽspŠÛ:ÏôìÂÈÝ+gÍþ9ÓÝžS\x18\x18 \rÚ²¸0Ž\x1e˵Fóó\x13îÓ\–å*—íîÿš\x12‚\r£\rî”+RƒGÒØ|&OØl\x13$\x10Æ\x04	Ñ PDç³Sã6þzø¢vO¦NÐÏ\x19dê7jZÞé’_½áõLóí\x16C\x02—=ô2\x7fÜ\x04€~i\x04\x1a ×fh¨\x14?Ç^ɏL>*V^Öùé2â~°¾Ëzebk&\f³Dr¥T•gÍWÓ7E‡jÕ$‰,Žp„\x14û¹\bEHò\x11Ês¾„#¨1ܨ®¬‚.™f¶N’‰\x03½\x16\x0fm`\rd+4Š\x01Ý”eB\x11ΞT\x1d+ã\œžÿâZQЇ¥Ÿ1\x14£^\ɾš\x15“?UòáG|¢¤h\:_¯ð\rŒ\x17\x17òéž•‰U\x1eôOŸ½zÙGí=vt\x16ËB’¼:ÒX\x10\vnO\x17÷F×\x10
7Å¿‘®àÊ7Û£½|”’àñ\x06%\x1a)܍“fª\x13W÷z^[Ý®^¡}CGÀsÔHÐðäâ…u¢\rUBe.JþTV7ü«òLÍlÛÄë\v/0äqß \b¿ã\x02ú\x0fªÁyz5Z‡=r|¦·ôKøŒßµ¹Ajy|M1%K\x10™¼k\x1f-vï^\x7f&5`ÕdÁ^´[’os.KàÇasåKw%Ɇ\x1feÊÆõ©]É\x10àÊqG¡Ð¸¯ñ‹Æäƒç\fÇ/\x1aìžÚ÷ÔNG;ƒjr´þ\x17\rô&ŒÝ\x13kÒNê#ëG\aí\x028ä]Qÿ‡›Xà4:·¡×¬ûÔ³sÔ§Šsu\x10ÞàЖ\x03[\x01@‹4Ø`Zç"ëçy\x10:ý€ñúE Ù8±`Ìr|Ýèߌ÷×5rtÈ\x02H#/Ùøæ‹ÑÒÆ}ë¢^[¿H¶{\x1eh(6éÿœFëÆ
`э¼QÄ4ڽدyÊžœä\x18ùôè µ“n÷ôt¤§±¶Cîêa\x153¢±wÛ/¥þ«¢\x12‚\x1f
\x1cÈÿX¸ˆ\x1d>\x15øßä¿\x03PK\x01\x02\x14\0\x14\0\x02\0\b\0Ü\x0590w¨L>t\r\0\0Ð\x0e\0\0\v\0\0\0\0\0\0\0\0\0 \0\0\0\0\0\0\0message.exePK\x05\x06\0\0\0\0\x01\0\x01\09\0\0\0\r\0\0\0\0

^ permalink raw reply

* [uml-devel] Re: PATCH kernel/umid.c
From: Jeff Dike @ 2004-01-28  1:46 UTC (permalink / raw)
  To: Dan Shearer; +Cc: user-mode-linux-devel
In-Reply-To: <20040126124708.GH4203@erizo.shearer.org>

dan@shearer.org said:
> -                       return(0); 
> +                       return(1);

I did the return(0) on purpose because, even though initcall procedures are
declared as returning an int, do_initcalls ignores it.

So, I added a comment there instead of changing the return value.

> In addition, umid.c seems to be a bit inconsistent as to what rates an
> exit(1) and what just does return(1). 

Stuff that's done early, before the kernel is actually running, rates an 
exit(1).  Everything else gets a return(1).  I don't always follow this rule,
but I did a quick check of umid.c and it looks OK.

				Jeff


				Jeff



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

* [uml-devel] Re: [PATCH] mconsole fixes
From: Jeff Dike @ 2004-01-28  1:46 UTC (permalink / raw)
  To: Dan Shearer; +Cc: user-mode-linux-devel
In-Reply-To: <20040126024617.GB4203@erizo.shearer.org>

dan@shearer.org said:
> + * instance over a local pipe connection. This tool does not 
> + * (since uml_mconsole version 1) need to be in sync with the version
> + * of the UML kernel since the commands and their implementation 
> + * are within UML.

The version does need to match.  UML will only talk to one version of mconsole.

The smarts are all in the kernel, but they do need to agree on the format of
the request and the response.

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

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.

				Jeff



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

* [announce] 2.6.2-rc2-kj1 patchset
From: Randy.Dunlap @ 2004-01-28  1:14 UTC (permalink / raw)
  To: kjo; +Cc: lkml


(fairly small this time, several patches recently merged,
and I'm still reviewing others.)


patch is at:
http://developer.osdl.org/rddunlap/kj-patches/2.6.2-rc2/2.6.2-rc2-kj1.patch.bz2  [2004-01-27]

M: merged at kernel.org;   mm: in -mm;   tx: sent;   mntr: maintainer merged;

This patch applies to linux-2.6.2-rc2.

new (for 2.6.2-rc2):  [2004-01-27]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
add/	ide_pci_triflex_not_procfs.patch
	From: Luiz Fernando Capitulino <lcapitulino@prefeitura.sp.gov.br>

add/	ps2esdi_typos.patch
	From: Timmy Yee <shoujun@masterofpi.org>

add/	fbcmap_kmalloc.patch
	From: Leann Ogasawara <ogasawara@osdl.org>

add	vga16fb_audit.patch
	From: Leann Ogasawara <ogasawara@osdl.org>

previous (for 2.6.2-rc1):  [2004-01-23] [not announced]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tx/	errno_numbers_assembly.patch
	From: Danilo Piazzalunga <danilopiazza@libero.it>
	to akpm: 2004.0126;

drop/	ide_tape_kmalloc_fail.patch
	From: Eugene Teo <eugene.teo@eugeneteo.net>
	looks wrong:  can't just return without doing work;

mm/	linux_sound_c99_init.patch
	From: "Maciej Soltysiak" <solt@dns.toxicfilms.tv>
	to akpm/perex: 2004.0124;

drop/	parameter_typos.patch
	From: "Maciej Soltysiak" <solt@dns.toxicfilms.tv>
	don't worry about spellos in comments;

previous (for 2.6.1-bk6):  [2004-01-21]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

tx/	aha1542_kmalloc_type.patch
	From: Timmy Yee <shoujun@masterofpi.org>
	to linux-scsi 2004.0124;

tx/	aha1542_qcommand_return.patch
	From: Timmy Yee <shoujun@masterofpi.org>
	to linux-scsi 2004.0124;

mm/	char_dz_vrfy_area.patch
	From: Domen Puncer <domen@coderock.org>
	to akpm: 2004.0124;

mm/	config_sysrq.patch
	From: Domen Puncer <domen@coderock.org>
	to akpm: 2004.0124;

mntr/	mcfserial_remove_casts_args.patch
	From: Domen Puncer <domen@coderock.org>
	to gerg@snapgear.com 2004.0124;

mntr/	netdev_get_stats.patch
	From: Domen Puncer <domen@coderock.org>
	to netdev/davem: 2004.0124;

tx/	scsi_config_doc.patch
	From: Jean Delvare <khali@linux-fr.org>
	to linux-scsi 2004.0124;

mntr/	saa7146_hlp_min_max.patch
	From: Eugene Teo <eugene.teo@eugeneteo.net>
	to maint: 2004.0124;

previous (for 2.6.1-bk4):  [2004-01-16]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
mntr/	config_ledman_rm.patch
	From: Domen Puncer <domen@coderock.org>
	to gerg@snapgear.com 2004.0124;

mntr/	ipt_register_target_retval.patch
	From: Daniele Bellucci <bellucda@tiscali.it>
	to netdev/davem: 2004.0124;

drop/	kconfig_cleanups_v1.patch
	From: Matthew Wilcox <willy@debian.org>
  drop	drivers/block/Kconfig: merge conflicts
  drop	drivers/video/console/Kconfig: merge conflicts
  drop	drivers/i2c/*/Kconfig: already merged
  	Willy to handle with akpm.

add?	kswapd_init_fail.patch
	From: Eugene Teo <eugene.teo@eugeneteo.net>

add/	lmc_proto_raw_h_rm.patch
	From: Domen Puncer <domen@coderock.org>

mntr/	netdev_rm_casts.patch
	From: Carlo Perassi <carlo@linux.it>
	to netdev/jgarzik: 2004.0124;

mntr/	s390_net_ctctty_putuser.patch
	From: Domen Puncer <domen@coderock.org>
	(rediffed)
	sent to s390 mntr: 2004.0124;

add/	setup_bootmem_fail.patch
	From: Eugene Teo <eugene.teo@eugeneteo.net>

?add	skfddi_regions_pciupdate.patch
	From: Matthew Wilcox <willy@debian.org>

drop/	acpi_boot_message_typo.patch
	From: Simon Richard Grint <rgrint@mrtall.compsoc.man.ac.uk>
	no longer applicable: function was removed;

mntr/	cpcihp_zt5550_iounmap.patch
	From: Leann Ogasawara <ogasawara@osdl.org>
	to gregkh: 2004.0124;

mntr/	mfcserial_vrfyarea.patch
	From: Domen Puncer <domen@coderock.org>
	to gerg@snapgear.com 2004.0124;

tx/	vga16fb.c_iounmap.patch
	From: Leann Ogasawara <ogasawara@osdl.org>
	to akpm/mntr: 2004.0126;

tx/	vgastate.c_iounmap.patch
	From: Leann Ogasawara <ogasawara@osdl.org>
	to akpm/mntr: 2004.0126;

drop/	tc35815.c_iounmap.patch
	From: Leann Ogasawara <ogasawara@osdl.org>
	sent to jgarzik/netdev: 2004.0118;
	already in netdev patchset;

drop/	depca_iounmap.patch
	From: Leann Ogasawara <ogasawara@osdl.org>
	already in netdev patchset;

tx/	dgrs_iounmap.patch
	From: Leann Ogasawara <ogasawara@osdl.org>
	sent to jgarzik/netdev: 2004.0118;

###


--
~Randy
kernel-janitors project:  http://janitor.kernelnewbies.org/

^ permalink raw reply

* [Kernel-janitors] [announce] 2.6.2-rc2-kj1 patchset
From: Randy.Dunlap @ 2004-01-28  1:14 UTC (permalink / raw)
  To: kjo; +Cc: lkml


(fairly small this time, several patches recently merged,
and I'm still reviewing others.)


patch is at:
http://developer.osdl.org/rddunlap/kj-patches/2.6.2-rc2/2.6.2-rc2-kj1.patch.bz2  [2004-01-27]

M: merged at kernel.org;   mm: in -mm;   tx: sent;   mntr: maintainer merged;

This patch applies to linux-2.6.2-rc2.

new (for 2.6.2-rc2):  [2004-01-27]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
add/	ide_pci_triflex_not_procfs.patch
	From: Luiz Fernando Capitulino <lcapitulino@prefeitura.sp.gov.br>

add/	ps2esdi_typos.patch
	From: Timmy Yee <shoujun@masterofpi.org>

add/	fbcmap_kmalloc.patch
	From: Leann Ogasawara <ogasawara@osdl.org>

add	vga16fb_audit.patch
	From: Leann Ogasawara <ogasawara@osdl.org>

previous (for 2.6.2-rc1):  [2004-01-23] [not announced]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tx/	errno_numbers_assembly.patch
	From: Danilo Piazzalunga <danilopiazza@libero.it>
	to akpm: 2004.0126;

drop/	ide_tape_kmalloc_fail.patch
	From: Eugene Teo <eugene.teo@eugeneteo.net>
	looks wrong:  can't just return without doing work;

mm/	linux_sound_c99_init.patch
	From: "Maciej Soltysiak" <solt@dns.toxicfilms.tv>
	to akpm/perex: 2004.0124;

drop/	parameter_typos.patch
	From: "Maciej Soltysiak" <solt@dns.toxicfilms.tv>
	don't worry about spellos in comments;

previous (for 2.6.1-bk6):  [2004-01-21]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

tx/	aha1542_kmalloc_type.patch
	From: Timmy Yee <shoujun@masterofpi.org>
	to linux-scsi 2004.0124;

tx/	aha1542_qcommand_return.patch
	From: Timmy Yee <shoujun@masterofpi.org>
	to linux-scsi 2004.0124;

mm/	char_dz_vrfy_area.patch
	From: Domen Puncer <domen@coderock.org>
	to akpm: 2004.0124;

mm/	config_sysrq.patch
	From: Domen Puncer <domen@coderock.org>
	to akpm: 2004.0124;

mntr/	mcfserial_remove_casts_args.patch
	From: Domen Puncer <domen@coderock.org>
	to gerg@snapgear.com 2004.0124;

mntr/	netdev_get_stats.patch
	From: Domen Puncer <domen@coderock.org>
	to netdev/davem: 2004.0124;

tx/	scsi_config_doc.patch
	From: Jean Delvare <khali@linux-fr.org>
	to linux-scsi 2004.0124;

mntr/	saa7146_hlp_min_max.patch
	From: Eugene Teo <eugene.teo@eugeneteo.net>
	to maint: 2004.0124;

previous (for 2.6.1-bk4):  [2004-01-16]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
mntr/	config_ledman_rm.patch
	From: Domen Puncer <domen@coderock.org>
	to gerg@snapgear.com 2004.0124;

mntr/	ipt_register_target_retval.patch
	From: Daniele Bellucci <bellucda@tiscali.it>
	to netdev/davem: 2004.0124;

drop/	kconfig_cleanups_v1.patch
	From: Matthew Wilcox <willy@debian.org>
  drop	drivers/block/Kconfig: merge conflicts
  drop	drivers/video/console/Kconfig: merge conflicts
  drop	drivers/i2c/*/Kconfig: already merged
  	Willy to handle with akpm.

add?	kswapd_init_fail.patch
	From: Eugene Teo <eugene.teo@eugeneteo.net>

add/	lmc_proto_raw_h_rm.patch
	From: Domen Puncer <domen@coderock.org>

mntr/	netdev_rm_casts.patch
	From: Carlo Perassi <carlo@linux.it>
	to netdev/jgarzik: 2004.0124;

mntr/	s390_net_ctctty_putuser.patch
	From: Domen Puncer <domen@coderock.org>
	(rediffed)
	sent to s390 mntr: 2004.0124;

add/	setup_bootmem_fail.patch
	From: Eugene Teo <eugene.teo@eugeneteo.net>

?add	skfddi_regions_pciupdate.patch
	From: Matthew Wilcox <willy@debian.org>

drop/	acpi_boot_message_typo.patch
	From: Simon Richard Grint <rgrint@mrtall.compsoc.man.ac.uk>
	no longer applicable: function was removed;

mntr/	cpcihp_zt5550_iounmap.patch
	From: Leann Ogasawara <ogasawara@osdl.org>
	to gregkh: 2004.0124;

mntr/	mfcserial_vrfyarea.patch
	From: Domen Puncer <domen@coderock.org>
	to gerg@snapgear.com 2004.0124;

tx/	vga16fb.c_iounmap.patch
	From: Leann Ogasawara <ogasawara@osdl.org>
	to akpm/mntr: 2004.0126;

tx/	vgastate.c_iounmap.patch
	From: Leann Ogasawara <ogasawara@osdl.org>
	to akpm/mntr: 2004.0126;

drop/	tc35815.c_iounmap.patch
	From: Leann Ogasawara <ogasawara@osdl.org>
	sent to jgarzik/netdev: 2004.0118;
	already in netdev patchset;

drop/	depca_iounmap.patch
	From: Leann Ogasawara <ogasawara@osdl.org>
	already in netdev patchset;

tx/	dgrs_iounmap.patch
	From: Leann Ogasawara <ogasawara@osdl.org>
	sent to jgarzik/netdev: 2004.0118;

###


--
~Randy
kernel-janitors project:  http://janitor.kernelnewbies.org/
_______________________________________________
Kernel-janitors mailing list
Kernel-janitors@lists.osdl.org
http://lists.osdl.org/mailman/listinfo/kernel-janitors

^ permalink raw reply

* [Bridge] Adding same physical port to multiple bridges
From: Abhijit Kumbhare @ 2004-01-28  1:10 UTC (permalink / raw)
  To: shemminger; +Cc: bridge

Hi,

Is there any particular reason why the same physical port cannot be 
added to multiple bridges? Is it because of STP?

If I am not using STP - can I change the code to have the same physical 
port in 2 VLANs? Is that a safe change?

Thanks,
Abhijit


^ permalink raw reply

* [patch] 2.4.25-pre6 Periodic check for outstanding MCA/INIT records
From: Keith Owens @ 2004-01-28  1:09 UTC (permalink / raw)
  To: linux-ia64

Tony, this goes with your recent recoverable MCA patch where you
reported that the MCA records were only being logged on the next boot.
It compiles and boots, can you confirm that it picks up the recovered
MCA records every few minutes without needing a reboot?

--- 2.4.25-pre6/arch/ia64/kernel/salinfo.c	Wed Jan 28 12:08:10 2004
+++ 2.4.25-pre6/arch/ia64/kernel/salinfo.c	Wed Jan 28 12:07:12 2004
@@ -16,6 +16,9 @@
  *   Cache the record across multi-block reads from user space.
  *   Support > 64 cpus.
  *   Delete module_exit and MOD_INC/DEC_COUNT, salinfo cannot be a module.
+ *
+ * Jan 28 2004	kaos@sgi.com
+ *   Periodically check for outstanding MCA or INIT records.
  */
 
 #include <linux/types.h>
@@ -23,6 +26,7 @@
 #include <linux/module.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
+#include <linux/timer.h>
 #include <linux/vmalloc.h>
 
 #include <asm/semaphore.h>
@@ -187,6 +191,8 @@
 /* This routine is invoked in interrupt context.  Note: mca.c enables
  * interrupts before calling this code for CMC/CPE.  MCA and INIT events are
  * not irq safe, do not call any routines that use spinlocks, they may deadlock.
+ * MCA and INIT records are recorded, a timer event will look for any
+ * outstanding events and wake up the user space code.
  *
  * The buffer passed from mca.c points to the output from ia64_log_get. This is
  * a persistent buffer but its contents can change between the interrupt and
@@ -232,6 +238,35 @@
 	}
 }
 
+/* Check for outstanding MCA/INIT records every 5 minutes (arbitrary) */
+#define SALINFO_TIMER_DELAY (5*60*HZ)
+static struct timer_list salinfo_timer;
+
+static void
+salinfo_timeout_check(struct salinfo_data *data)
+{
+	int i;
+	if (!data->open)
+		return;
+	for (i = 0; i < NR_CPUS; ++i) {
+		if (test_bit(i, &data->cpu_event)) {
+			/* double up() is not a problem, user space will see no
+			 * records for the additional "events".
+			 */
+			up(&data->sem);
+		}
+	}
+}
+
+static void 
+salinfo_timeout (unsigned long arg)
+{
+	salinfo_timeout_check(salinfo_data + SAL_INFO_TYPE_MCA);
+	salinfo_timeout_check(salinfo_data + SAL_INFO_TYPE_INIT);
+	salinfo_timer.expires = jiffies + SALINFO_TIMER_DELAY;
+	add_timer(&salinfo_timer);
+}
+
 static int
 salinfo_event_open(struct inode *inode, struct file *file)
 {
@@ -571,6 +606,11 @@
 
 	*sdir++ = salinfo_dir;
 
+	init_timer(&salinfo_timer);
+	salinfo_timer.expires = jiffies + SALINFO_TIMER_DELAY;
+	salinfo_timer.function = &salinfo_timeout;
+	add_timer(&salinfo_timer);
+
 	return 0;
 }
 


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