Skip to content

Commit

Permalink
[PATCH] powerpc/pseries: mutex lock to serialize EEH event processing
Browse files Browse the repository at this point in the history
This forces the processing of EEH PCI events to be serialized,
using a very simple mutex lock. This serialization is required to
avoid races involving additional PCI device failures that may occur
during the recovery phase of a previous failure.

Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
  • Loading branch information
Linas Vepstas authored and Paul Mackerras committed Apr 1, 2006
1 parent f18dd51 commit 8c33fd1
Showing 1 changed file with 18 additions and 12 deletions.
30 changes: 18 additions & 12 deletions arch/powerpc/platforms/pseries/eeh_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
*/

#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/pci.h>
#include <linux/workqueue.h>
#include <asm/eeh_event.h>
#include <asm/ppc-pci.h>

Expand All @@ -37,14 +39,18 @@ LIST_HEAD(eeh_eventlist);
static void eeh_thread_launcher(void *);
DECLARE_WORK(eeh_event_wq, eeh_thread_launcher, NULL);

/* Serialize reset sequences for a given pci device */
DEFINE_MUTEX(eeh_event_mutex);

/**
* eeh_event_handler - dispatch EEH events. The detection of a frozen
* slot can occur inside an interrupt, where it can be hard to do
* anything about it. The goal of this routine is to pull these
* detection events out of the context of the interrupt handler, and
* re-dispatch them for processing at a later time in a normal context.
*
* eeh_event_handler - dispatch EEH events.
* @dummy - unused
*
* The detection of a frozen slot can occur inside an interrupt,
* where it can be hard to do anything about it. The goal of this
* routine is to pull these detection events out of the context
* of the interrupt handler, and re-dispatch them for processing
* at a later time in a normal context.
*/
static int eeh_event_handler(void * dummy)
{
Expand All @@ -64,31 +70,31 @@ static int eeh_event_handler(void * dummy)
event = list_entry(eeh_eventlist.next, struct eeh_event, list);
list_del(&event->list);
}

if (event)
eeh_mark_slot(event->dn, EEH_MODE_RECOVERING);

spin_unlock_irqrestore(&eeh_eventlist_lock, flags);

if (event == NULL)
break;

/* Serialize processing of EEH events */
mutex_lock(&eeh_event_mutex);
eeh_mark_slot(event->dn, EEH_MODE_RECOVERING);

printk(KERN_INFO "EEH: Detected PCI bus error on device %s\n",
pci_name(event->dev));

handle_eeh_events(event);

eeh_clear_slot(event->dn, EEH_MODE_RECOVERING);

pci_dev_put(event->dev);
kfree(event);
mutex_unlock(&eeh_event_mutex);
}

return 0;
}

/**
* eeh_thread_launcher
*
* @dummy - unused
*/
static void eeh_thread_launcher(void *dummy)
Expand Down

0 comments on commit 8c33fd1

Please sign in to comment.