Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 16 Jun 2006 16:51:43 GMT
From:      Dirk Jagdmann <dj@secion.de>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   i386/99039: SATA timeouts on HP DL140 G2
Message-ID:  <200606161651.k5GGphOd025449@www.freebsd.org>
Resent-Message-ID: <200606161700.k5GH0aMe014090@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         99039
>Category:       i386
>Synopsis:       SATA timeouts on HP DL140 G2
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-i386
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Jun 16 17:00:35 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator:     Dirk Jagdmann
>Release:        6.1
>Organization:
Secion GmbH
>Environment:
FreeBSD shape1.net 6.1-RELEASE-p2 FreeBSD 6.1-RELEASE-p2 #2: Fri Jun 16 16:21:50 CEST 2006     root@shape1.net:/usr/obj/usr/src/sys/GENERIC  i386
>Description:
The HP DL140 G2 features the Intel ICH5 SATA controller. When using FreeBSD 6.1 together with BIOS v1.16 the system suffers from some sort of SATA Timeouts when the harddrive is accessed after about 30 (or more) seconds of idle time. For example if you load a text file into an editor, then edit your text (and thus not doing any harddisk IO) for 1min and then save your text, the system will hang for ~3s before saving the text. Occasionally the kernel generates a message like:
kernel: ad2: TIMEOUT - WRITE_DMA retrying (1 retry left) LBA=55292287

Apart from the timeouts the system seems to be stable and working fine. There is no data corruption when accessing the harddisk.
>How-To-Repeat:
I have made a test programm which will measure some harddisk action and then wait for some time, before repeating the action. If the waited timespan is 31,61 or 91 seconds you see a delay of ~3200ms before the first action finishes. Further code comments are unfortunately in german:

// timeout.cpp 2006-06-16 Dirk Jagdmann <dj@secion.de>
//
// Testprogramm um die SATA Timeouts auf DL140G2 mit BIOS Version 1.16
// zu reproduzieren.
//
// Das Programm misst die Ausfuehrungszeit des Kommandos CMD in Millisekunden.
// Auf einem System ohne Last sollte die Zeit unter 10ms liegen. Nach jeweils
// 10 Ausfuehrungen von CMD wird eine Zeitspanne gewartet (1,31,61,91,121
// Sekunden). Hat das System den SATA Timeout, so ist nach der Wartezeit die
// erstmalige Ausfuehrungszeit von CMD auf ~3200ms erhoeht.
//
// Der Fehler tritt auf bei DL140G2 BIOS 1.16 FreeBSD 6.1 GENERIC kernel.
// Ein Update auf BIOS 1.17 behebt den Fehler, SATA Timeouts treten dann nicht
// mehr auf.
//
// Die Ausgabe des Programms sind drei Zahlen. Die erste Zahl gibt die
// laufende Nummer des Aufrufs von CMD aus. Nach 300 Aufrufen beendet sich
// das Programm. Die zweite Zahl zeigt die gewartete Zeitspanne vor dem
// letzten Aufruf von CMD in Sekunden. Die dritte Zahl zeigt die
// Ausfuehrungszeit von CMD in Millisekunden. Betraegt die Ausfuehrungszeit
// weniger als 10ms, so wird die aktuelle Zeile ueberschrieben.
//
// Zum Programmende wird eine Matrix der gemessenen Zeiten ausgegeben.

#include <stdlib.h>
#include <map>
#include <iostream>
#include <vector>
#include <stdint.h>
#include <sys/time.h>

#define CMD "ls -l /etc > /tmp/doj"

inline uint32_t timeGetTime()
{
  struct timeval tv;
  if(gettimeofday(&tv, NULL) == 0)
    return tv.tv_sec*1000 + tv.tv_usec/1000;
  return 0;
}

int main()
{
  typedef std::vector<int> stat_v;
  typedef std::map<int, stat_v> stat_t;
  stat_t stat;

  int z=0, s=1;
  while(++z<300)
    {
      sleep(s);

      for(int j=0; j<10; j++)
	{
	  const uint32_t before=timeGetTime();
	  system(CMD);
	  const int t=timeGetTime()-before;
	  stat[s].push_back(t);

	  std::cout << "\r#" << z << "\t" << s << "s \t" << t << "ms    " << std::flush;
	  if(t>=10)
	    std::cout << std::endl;
	}

      s+=30;
      if(s>=122)
	s=1;
    }

  for(stat_t::iterator i=stat.begin(); i!=stat.end(); ++i)
    {
      std::cout << i->first << ":\t";
      stat_v &v=stat[i->first];
      for(stat_v::iterator i=v.begin(); i!=v.end(); ++i)
	std::cout << *i << ' ';
      std::cout << std::endl;
    }

  return 0;
}

>Fix:
A BIOS update to version 1.17 fixes the timeout problem. The BIOS was downloaded from:
http://h18023.www1.hp.com/support/files/server/us/download/24573.html

>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200606161651.k5GGphOd025449>