summaryrefslogtreecommitdiff
path: root/Source/linux-fusion_8.1.2.patch
diff options
context:
space:
mode:
Diffstat (limited to 'Source/linux-fusion_8.1.2.patch')
-rwxr-xr-xSource/linux-fusion_8.1.2.patch541
1 files changed, 541 insertions, 0 deletions
diff --git a/Source/linux-fusion_8.1.2.patch b/Source/linux-fusion_8.1.2.patch
new file mode 100755
index 0000000..6156d4b
--- /dev/null
+++ b/Source/linux-fusion_8.1.2.patch
@@ -0,0 +1,541 @@
+diff -uNrb linux-fusion-8.1.1_or/linux/drivers/char/fusion/call.c linux-fusion-8.1.1/linux/drivers/char/fusion/call.c
+--- linux-fusion-8.1.1_or/linux/drivers/char/fusion/call.c 2009-03-31 15:04:32.000000000 +0200
++++ linux-fusion-8.1.1/linux/drivers/char/fusion/call.c 2010-05-07 20:15:33.000000000 +0200
+@@ -42,6 +42,7 @@
+
+ int call_id;
+ unsigned int serial;
++ int caller_pid;
+ } FusionCallExecution;
+
+ typedef struct {
+@@ -102,6 +103,31 @@
+ free_all_executions(call);
+ }
+
++
++static void print_call( FusionCall* call )
++{
++ FusionEntry *entry;
++ FusionLink *e;
++
++ entry = &call->entry;
++
++ printk( KERN_CRIT "%-2d %s, fid:%d, %d calls)",
++ entry->id,
++ entry->name[0] ? entry->name : "???",
++ call->fusion_id,
++ call->count);
++
++ fusion_list_foreach(e, call->executions) {
++ FusionCallExecution *exec = (FusionCallExecution *) e;
++
++ printk( "/%lx:%s",
++ exec->caller ? fusionee_id(exec->caller) : -1,
++ exec->executed ? "idle" : "busy" );
++ }
++
++ printk("\n");
++}
++
+ static void
+ fusion_call_print(FusionEntry * entry, void *ctx, struct seq_file *p)
+ {
+@@ -221,14 +247,21 @@
+ /* Transfer held skirmishs (locks). */
+ fusion_skirmish_transfer_all(dev, call->fusion_id,
+ fusionee_id(fusionee),
+- current->pid);
++ current->pid,
++ serial);
+
+ /* Unlock call and wait for execution result. TODO: add timeout? */
++
+ fusion_sleep_on(&execution->wait, &call->entry.lock, 0);
+
+ if (signal_pending(current)) {
+ /* Indicate that a signal was received and execution won't be freed by caller. */
+ execution->caller = NULL;
++ printk( KERN_EMERG "NDC signal_pending(current) -> exit from fusion_call_execute() without reclaiming our skirmishes. current->pid=%d, fid=0x%08x, call->fusion_id=%d\n",
++ current->pid,
++ (int)(fusionee_id(fusionee)),
++ call->fusion_id );
++
+ return -EINTR;
+ }
+
+@@ -300,6 +333,9 @@
+ /* FIXME: Caller might still have received a signal since check above. */
+ FUSION_ASSERT(execution->caller != NULL);
+
++ /* Return skirmishs. */
++ fusion_skirmish_return_all(dev, fusion_id, execution->caller_pid, execution->serial);
++
+ /* Wake up caller. */
+ wake_up_interruptible(&execution->wait);
+
+@@ -349,8 +385,11 @@
+ fusion_sleep_on(&execution->wait, &call->entry.lock, 0);
+
+ if (signal_pending(current))
++ {
++ printk( KERN_EMERG "NDC signal_pending(current) -> exit from fusion_call_destroy()\n");
+ return -EINTR;
+ }
++ }
+ } while (execution);
+
+ fusion_entry_destroy_locked(call->entry.entries, &call->entry);
+@@ -402,6 +441,7 @@
+ memset(execution, 0, sizeof(FusionCallExecution));
+
+ execution->caller = caller;
++ execution->caller_pid = current->pid;
+ execution->call_id = call->entry.id;
+ execution->serial = serial;
+
+diff -uNrb linux-fusion-8.1.1_or/linux/drivers/char/fusion/skirmish.c linux-fusion-8.1.1/linux/drivers/char/fusion/skirmish.c
+--- linux-fusion-8.1.1_or/linux/drivers/char/fusion/skirmish.c 2009-03-31 15:04:32.000000000 +0200
++++ linux-fusion-8.1.1/linux/drivers/char/fusion/skirmish.c 2010-05-07 20:15:32.000000000 +0200
+@@ -52,6 +52,13 @@
+ FusionID transfer_from;
+ int transfer_from_pid;
+ int transfer_count;
++ unsigned int transfer_serial;
++
++ FusionID transfer2_to;
++ FusionID transfer2_from;
++ int transfer2_from_pid;
++ int transfer2_count;
++ unsigned int transfer2_serial;
+
+ #ifdef FUSION_DEBUG_SKIRMISH_DEADLOCK
+ int pre_acquis[MAX_PRE_ACQUISITIONS];
+@@ -69,6 +76,87 @@
+ static unsigned int m_pidlocks[PID_MAX_DEFAULT + 1]; /* FIXME: find cleaner, but still fast method */
+ static sigset_t m_sigmask;
+
++
++static void
++print_skirmish_internal( FusionSkirmish* skirmish, const char* pHeader )
++{
++ FusionEntry *entry;
++ char p[16];
++ struct timeval now;
++ static kaboemcount = 100;
++
++ // kaboemcount--;
++
++ do_gettimeofday(&now);
++
++ entry = &skirmish->entry;
++
++ if (entry->last_lock.tv_sec) {
++ int diff = ((now.tv_sec - entry->last_lock.tv_sec) * 1000 +
++ (now.tv_usec - entry->last_lock.tv_usec) / 1000);
++
++ if (diff < 1000) {
++ sprintf(p, "%3d ms ", diff);
++ } else if (diff < 1000000) {
++ sprintf(p, "%3d.%d s ", diff / 1000,
++ (diff % 1000) / 100);
++ } else {
++ diff = (now.tv_sec - entry->last_lock.tv_sec +
++ (now.tv_usec -
++ entry->last_lock.tv_usec) / 1000000);
++
++ sprintf(p, "%3d.%d h ", diff / 3600,
++ (diff % 3600) / 360);
++ }
++ } else
++ sprintf(p, " -.- ");
++
++
++ printk( "%s %s %-3d.%03d %d %-18s [1] t:%d f:%d fpid:%-4d c:%d s:%d [2] t:%d f:%d fpid:%-4d c:%d s:%d - c:%d f:%d p:%-4d w:%d\n",
++ pHeader ? pHeader : " ",
++ p,
++ entry->last_lock.tv_sec,
++ (entry->last_lock.tv_usec)/1000000 ,
++ entry->id,
++ entry->name[0] ? entry->name : "???",
++
++ skirmish->transfer_to,
++ skirmish->transfer_from,
++ skirmish->transfer_from_pid,
++ skirmish->transfer_count,
++ skirmish->transfer_serial,
++
++ skirmish->transfer2_to,
++ skirmish->transfer2_from,
++ skirmish->transfer2_from_pid,
++ skirmish->transfer2_count,
++ skirmish->transfer2_serial,
++
++ skirmish->lock_count,
++ skirmish->lock_fid,
++ skirmish->lock_pid,
++ skirmish->entry.waiters
++ );
++
++ if( kaboemcount <= 0 )
++ {
++ printk( KERN_EMERG "boem !\n" );
++ kill_pgrp(task_pgrp(current), SIGSEGV, 1);
++ while(1)
++ {
++ yield();
++ }
++ }
++
++}
++
++static void
++print_skirmish( FusionSkirmish* skirmish )
++{
++ print_skirmish_internal( skirmish, KERN_EMERG " skirmish" );
++}
++
++
+ #ifdef FUSION_BLOCK_SIGNALS
+ static int skirmish_signal_handler(void *ctx)
+ {
+@@ -77,7 +165,7 @@
+ return 1;
+ }
+
+- printk(KERN_DEBUG "FusionSkirmish: Blocking signal for process %d!\n",
++ printk(KERN_EMERG "FusionSkirmish: Blocking signal for process %d!\n",
+ current->pid);
+
+ return 0;
+@@ -111,20 +199,23 @@
+ }
+ }
+ #endif
+-
+- if (skirmish->lock_fid) {
+- if (skirmish->entry.waiters)
+- seq_printf(p, " - %dx [0x%08x] (%d) %d WAITING\n",
+- skirmish->lock_count, skirmish->lock_fid,
+- skirmish->lock_pid, skirmish->entry.waiters);
+- else
+- seq_printf(p, " - %dx [0x%08x] (%d)\n",
+- skirmish->lock_count, skirmish->lock_fid,
+- skirmish->lock_pid);
+- return;
+- }
+-
+- seq_printf(p, "\n");
++ seq_printf(p, "[1] t:%d, f:%d, fpid:%d, c:%d s:%d, [2] t:%d, f:%d, fpid:%d, c:%d, s:%d",
++ skirmish->transfer_to,
++ skirmish->transfer_from,
++ skirmish->transfer_from_pid,
++ skirmish->transfer_count,
++ skirmish->transfer_serial,
++ skirmish->transfer2_to,
++ skirmish->transfer2_from,
++ skirmish->transfer2_from_pid,
++ skirmish->transfer2_count,
++ skirmish->transfer2_serial );
++ seq_printf(p, ", c:%d, f:0x%08x, p:%d, waiters:%d\n",
++ skirmish->lock_count,
++ skirmish->lock_fid,
++ skirmish->lock_pid,
++ skirmish->entry.waiters
++ );
+ }
+
+ FUSION_ENTRY_CLASS(FusionSkirmish, skirmish, NULL, NULL, fusion_skirmish_print)
+@@ -245,11 +336,14 @@
+
+ up(&dev->skirmish.lock);
+
+- while (skirmish->lock_pid || (skirmish->transfer_to != 0 &&
+- fusionee_dispatcher_pid(dev,
+- skirmish->
+- transfer_to) !=
+- current->pid)) {
++
++ while ( skirmish->lock_pid
++ || ( (skirmish->transfer2_to == 0)
++ && skirmish->transfer_to
++ && (fusionee_dispatcher_pid(dev, skirmish-> transfer_to) != current->pid))
++ || ( skirmish->transfer2_to
++ && (fusionee_dispatcher_pid(dev, skirmish-> transfer2_to) != current->pid)) )
++ {
+ ret = fusion_skirmish_wait(skirmish, NULL);
+ if (ret)
+ return ret;
+@@ -283,11 +377,13 @@
+
+ dev->stat.skirmish_prevail_swoop++;
+
+- if (skirmish->lock_fid || (skirmish->transfer_to != 0 &&
+- fusionee_dispatcher_pid(dev,
+- skirmish->
+- transfer_to) !=
+- current->pid)) {
++ if ( skirmish->lock_fid
++ || ( (skirmish->transfer2_to == 0)
++ && skirmish->transfer_to
++ && (fusionee_dispatcher_pid(dev, skirmish->transfer_to) != current->pid))
++ || ( skirmish->transfer2_to
++ && (fusionee_dispatcher_pid(dev, skirmish-> transfer2_to) != current->pid)) )
++ {
+ if (skirmish->lock_pid == current->pid) {
+ skirmish->lock_count++;
+ skirmish->lock_total++;
+@@ -515,6 +611,8 @@
+ break;
+
+ case -EINTR:
++ printk( KERN_EMERG "NDC fusion_skirmish_wait EINTR()\n");
++
+ /* Return immediately upon signal. */
+ FUSION_SKIRMISH_LOG
+ ("FusionSkirmish: Interrupted while waiting for notification!\n");
+@@ -538,6 +636,7 @@
+ break;
+
+ case -EINTR:
++ printk( KERN_EMERG "NDC fusion_skirmish_wait 2 EINTR()\n");
+ /* Return immediately upon signal. */
+ FUSION_SKIRMISH_LOG
+ ("FusionSkirmish: Interrupted while waiting for relock!\n");
+@@ -614,11 +713,26 @@
+ wake_up_interruptible_all(&skirmish->entry.wait);
+ }
+
++ if (skirmish->transfer2_from == fusion_id) {
++ skirmish->transfer2_to = 0;
++ skirmish->transfer2_from = 0;
++ skirmish->transfer2_from_pid = 0;
++ skirmish->transfer2_count = 0;
++
++ wake_up_interruptible_all(&skirmish->entry.wait);
++ }
++
+ if (skirmish->transfer_from == fusion_id) {
+- skirmish->transfer_to = 0;
+- skirmish->transfer_from = 0;
+- skirmish->transfer_from_pid = 0;
+- skirmish->transfer_count = 0;
++ skirmish->transfer_to = skirmish->transfer2_to;
++ skirmish->transfer_from = skirmish->transfer2_from;
++ skirmish->transfer_from_pid = skirmish->transfer2_from_pid;
++ skirmish->transfer_count = skirmish->transfer2_count;
++ if (skirmish->transfer2_to) {
++ skirmish->transfer2_to = 0;
++ skirmish->transfer2_from = 0;
++ skirmish->transfer2_from_pid = 0;
++ skirmish->transfer2_count = 0;
++ }
+
+ wake_up_interruptible_all(&skirmish->entry.wait);
+ }
+@@ -650,11 +764,26 @@
+ wake_up_interruptible_all(&skirmish->entry.wait);
+ }
+
++ if (skirmish->transfer2_from_pid == pid) {
++ skirmish->transfer2_to = 0;
++ skirmish->transfer2_from = 0;
++ skirmish->transfer2_from_pid = 0;
++ skirmish->transfer2_count = 0;
++
++ wake_up_interruptible_all(&skirmish->entry.wait);
++ }
++
+ if (skirmish->transfer_from_pid == pid) {
+- skirmish->transfer_to = 0;
+- skirmish->transfer_from = 0;
+- skirmish->transfer_from_pid = 0;
+- skirmish->transfer_count = 0;
++ skirmish->transfer_to = skirmish->transfer2_to;
++ skirmish->transfer_from = skirmish->transfer2_from;
++ skirmish->transfer_from_pid = skirmish->transfer2_from_pid;
++ skirmish->transfer_count = skirmish->transfer2_count;
++ if (skirmish->transfer2_to) {
++ skirmish->transfer2_to = 0;
++ skirmish->transfer2_from = 0;
++ skirmish->transfer2_from_pid = 0;
++ skirmish->transfer2_count = 0;
++ }
+
+ wake_up_interruptible_all(&skirmish->entry.wait);
+ }
+@@ -667,7 +796,7 @@
+
+ void
+ fusion_skirmish_transfer_all(FusionDev * dev,
+- FusionID to, FusionID from, int from_pid)
++ FusionID to, FusionID from, int from_pid, unsigned int serial)
+ {
+ FusionLink *l;
+
+@@ -679,6 +808,7 @@
+ down(&skirmish->entry.lock);
+
+ if ( (skirmish->lock_pid == from_pid) && (skirmish->transfer_to == 0) ) {
++ if (skirmish->transfer_to == 0) {
+ FUSION_ASSERT(skirmish->transfer_from == 0);
+ FUSION_ASSERT(skirmish->transfer_from_pid == 0);
+ FUSION_ASSERT(skirmish->transfer_count == 0);
+@@ -689,6 +818,24 @@
+ skirmish->transfer_from_pid = from_pid;
+ skirmish->transfer_count = skirmish->lock_count;
+
++ skirmish->transfer_serial = serial;
++
++ skirmish->lock_fid = 0;
++ skirmish->lock_pid = 0;
++ skirmish->lock_count = 0;
++
++ wake_up_interruptible_all(&skirmish->entry.wait);
++ } else if (skirmish->transfer2_to == 0) {
++ FUSION_ASSERT(skirmish->transfer2_from == 0);
++ FUSION_ASSERT(skirmish->transfer2_from_pid == 0);
++ FUSION_ASSERT(skirmish->transfer2_count == 0);
++ FUSION_ASSERT(skirmish->lock_count > 0);
++
++ skirmish->transfer2_to = to;
++ skirmish->transfer2_from = from;
++ skirmish->transfer2_from_pid = from_pid;
++ skirmish->transfer2_count = skirmish->lock_count;
++ skirmish->transfer2_serial = serial;
+ skirmish->lock_fid = 0;
+ skirmish->lock_pid = 0;
+ skirmish->lock_count = 0;
+@@ -695,6 +843,7 @@
+
+ wake_up_interruptible_all(&skirmish->entry.wait);
+ }
++ }
+
+ up(&skirmish->entry.lock);
+ }
+@@ -713,11 +862,18 @@
+
+ down(&skirmish->entry.lock);
+
+- if (skirmish->transfer_from_pid == from_pid) {
++ if ( (skirmish->transfer2_to == 0)
++ && skirmish->transfer_to
++ && (skirmish->transfer_from_pid == from_pid) )
++ {
+ FUSION_ASSERT(skirmish->transfer_to != 0);
+ FUSION_ASSERT(skirmish->transfer_from != 0);
+ FUSION_ASSERT(skirmish->transfer_count > 0);
+- FUSION_ASSUME(skirmish->lock_pid == 0);
++ if( skirmish->lock_pid != -1 )
++ {
++ print_skirmish( skirmish );
++ }
++ FUSION_ASSERT(skirmish->lock_pid == -1);
+
+ skirmish->lock_fid = skirmish->transfer_from;
+ skirmish->lock_pid = skirmish->transfer_from_pid;
+@@ -727,6 +883,68 @@
+ skirmish->transfer_from = 0;
+ skirmish->transfer_from_pid = 0;
+ skirmish->transfer_count = 0;
++ } else if ( skirmish->transfer2_to
++ && (skirmish->transfer2_from_pid == from_pid) ) {
++ FUSION_ASSERT(skirmish->transfer2_to != 0);
++ FUSION_ASSERT(skirmish->transfer2_from != 0);
++ FUSION_ASSERT(skirmish->transfer2_count > 0);
++ FUSION_ASSERT(skirmish->lock_pid == -1);
++
++ skirmish->lock_fid = skirmish->transfer2_from;
++ skirmish->lock_pid = skirmish->transfer2_from_pid;
++ skirmish->lock_count = skirmish->transfer2_count;
++
++ skirmish->transfer2_to = 0;
++ skirmish->transfer2_from = 0;
++ skirmish->transfer2_from_pid = 0;
++ skirmish->transfer2_count = 0;
++ }
++ up(&skirmish->entry.lock);
++ }
++
++ up(&dev->skirmish.lock);
++}
++
++void fusion_skirmish_return_all(FusionDev * dev, int from_fusion_id, int to_pid, unsigned int serial)
++{
++ FusionLink *l;
++
++ down(&dev->skirmish.lock);
++
++ fusion_list_foreach(l, dev->skirmish.list) {
++ FusionSkirmish *skirmish = (FusionSkirmish *) l;
++
++ down(&skirmish->entry.lock);
++
++ if (skirmish->transfer2_to == 0) {
++ if ( skirmish->transfer_to == from_fusion_id &&
++ skirmish->transfer_from_pid == to_pid &&
++ skirmish->transfer_serial == serial )
++ {
++ FUSION_ASSERT(skirmish->transfer_from != 0);
++ FUSION_ASSERT(skirmish->transfer_count > 0);
++ if( skirmish->lock_count != 0 )
++ {
++ print_skirmish( skirmish );
++ }
++ FUSION_ASSERT(skirmish->lock_count == 0);
++ FUSION_ASSERT(skirmish->lock_fid == 0);
++ FUSION_ASSERT(skirmish->lock_pid == 0);
++
++ skirmish->lock_pid = -1;
++ }
++ }
++ else if (skirmish->transfer2_from_pid == to_pid &&
++ skirmish->transfer2_to == from_fusion_id &&
++ skirmish->transfer2_serial == serial )
++ {
++ FUSION_ASSERT(skirmish->transfer2_from != 0);
++ FUSION_ASSERT(skirmish->transfer2_count > 0);
++ FUSION_ASSERT(skirmish->lock_count == 0);
++ FUSION_ASSERT(skirmish->lock_fid == 0);
++ FUSION_ASSERT(skirmish->lock_pid == 0);
++
++ skirmish->lock_pid = -1;
+ }
+
+ up(&skirmish->entry.lock);
+@@ -734,3 +952,4 @@
+
+ up(&dev->skirmish.lock);
+ }
++
+diff -uNrb linux-fusion-8.1.1_or/linux/drivers/char/fusion/skirmish.h linux-fusion-8.1.1/linux/drivers/char/fusion/skirmish.h
+--- linux-fusion-8.1.1_or/linux/drivers/char/fusion/skirmish.h 2009-03-31 15:04:32.000000000 +0200
++++ linux-fusion-8.1.1/linux/drivers/char/fusion/skirmish.h 2010-05-07 20:15:31.000000000 +0200
+@@ -50,8 +50,10 @@
+ void fusion_skirmish_dismiss_all_from_pid(FusionDev * dev, int pid);
+
+ void fusion_skirmish_transfer_all(FusionDev * dev,
+- FusionID to, FusionID from, int from_pid);
++ FusionID to, FusionID from, int from_pid, unsigned int serial);
+
+ void fusion_skirmish_reclaim_all(FusionDev * dev, int from_pid);
+
++void fusion_skirmish_return_all(FusionDev * dev, int from_fusion_id, int to_fusion_id, unsigned int serial);
++
+ #endif
+diff -uNrb linux-fusion-8.1.1_or/Makefile linux-fusion-8.1.1/Makefile
+--- linux-fusion-8.1.1_or/Makefile 2009-03-31 15:04:32.000000000 +0200
++++ linux-fusion-8.1.1/Makefile 2010-06-04 23:41:54.140625000 +0200
+@@ -49,7 +49,7 @@
+
+ modules:
+ rm -f $(SUB)/Makefile
+- ln -s Makefile-2.$(K_PATCHLEVEL) $(SUB)/Makefile
++ cp $(SUB)/Makefile-2.$(K_PATCHLEVEL) $(SUB)/Makefile
+ echo kernel is in $(KERNEL_SOURCE) and version is $(K_SUBLEVEL)
+ ifeq ($(call check-version,2,6,24),1)
+ $(MAKE) -C $(KERNEL_BUILD) \
+
+
+