Dear Debian kernel team, I have backported (well, in fact, manually applied) Dan Williams patch (who is the maintainer of IOAT upstream) for the Debian 3.2 kernel. Please apply this patch. Note that I have tested it, and that I can confirm (as others did) that the issue is fixed after applying. This patch will be (or has already been?) applied upstream.
Cheers, Thomas Goirand (zigo)
diff -u -N -r a/debian/patches/bugfix/all/ioat_unsigned_long_to_dma_addr_t.patch b/debian/patches/bugfix/all/ioat_unsigned_long_to_dma_addr_t.patch --- a/debian/patches/bugfix/all/ioat_unsigned_long_to_dma_addr_t.patch 1970-01-01 00:00:00.000000000 +0000 +++ b/debian/patches/bugfix/all/ioat_unsigned_long_to_dma_addr_t.patch 2012-03-24 06:02:36.000000000 +0000 @@ -0,0 +1,168 @@ +diff -u -r -N a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c +--- a/drivers/dma/ioat/dma.c 2012-03-19 16:03:17.000000000 +0000 ++++ b/drivers/dma/ioat/dma.c 2012-03-24 05:50:59.000000000 +0000 +@@ -548,9 +548,9 @@ + PCI_DMA_TODEVICE, flags, 0); + } + +-unsigned long ioat_get_current_completion(struct ioat_chan_common *chan) ++dma_addr_t ioat_get_current_completion(struct ioat_chan_common *chan) + { +- unsigned long phys_complete; ++ dma_addr_t phys_complete; + u64 completion; + + completion = *chan->completion; +@@ -571,7 +571,7 @@ + } + + bool ioat_cleanup_preamble(struct ioat_chan_common *chan, +- unsigned long *phys_complete) ++ dma_addr_t *phys_complete) + { + *phys_complete = ioat_get_current_completion(chan); + if (*phys_complete == chan->last_completion) +@@ -582,14 +582,14 @@ + return true; + } + +-static void __cleanup(struct ioat_dma_chan *ioat, unsigned long phys_complete) ++static void __cleanup(struct ioat_dma_chan *ioat, dma_addr_t phys_complete) + { + struct ioat_chan_common *chan = &ioat->base; + struct list_head *_desc, *n; + struct dma_async_tx_descriptor *tx; + +- dev_dbg(to_dev(chan), "%s: phys_complete: %lx\n", +- __func__, phys_complete); ++ dev_dbg(to_dev(chan), "%s: phys_complete: %llx\n", ++ __func__, (unsigned long long) phys_complete); + list_for_each_safe(_desc, n, &ioat->used_desc) { + struct ioat_desc_sw *desc; + +@@ -655,7 +655,7 @@ + static void ioat1_cleanup(struct ioat_dma_chan *ioat) + { + struct ioat_chan_common *chan = &ioat->base; +- unsigned long phys_complete; ++ dma_addr_t phys_complete; + + prefetch(chan->completion); + +@@ -701,7 +701,7 @@ + mod_timer(&chan->timer, jiffies + COMPLETION_TIMEOUT); + spin_unlock_bh(&ioat->desc_lock); + } else if (test_bit(IOAT_COMPLETION_PENDING, &chan->state)) { +- unsigned long phys_complete; ++ dma_addr_t phys_complete; + + spin_lock_bh(&ioat->desc_lock); + /* if we haven't made progress and we have already +diff -u -r -N linux-2.6-3.2.12.orig/drivers/dma/ioat/dma.h linux-2.6-3.2.12/drivers/dma/ioat/dma.h +--- linux-2.6-3.2.12.orig/drivers/dma/ioat/dma.h 2012-03-19 16:03:17.000000000 +0000 ++++ linux-2.6-3.2.12/drivers/dma/ioat/dma.h 2012-03-24 05:52:30.000000000 +0000 +@@ -88,7 +88,7 @@ + struct ioat_chan_common { + struct dma_chan common; + void __iomem *reg_base; +- unsigned long last_completion; ++ dma_addr_t last_completion; + spinlock_t cleanup_lock; + dma_cookie_t completed_cookie; + unsigned long state; +@@ -333,7 +333,7 @@ + void __devexit ioat_dma_remove(struct ioatdma_device *device); + struct dca_provider * __devinit ioat_dca_init(struct pci_dev *pdev, + void __iomem *iobase); +-unsigned long ioat_get_current_completion(struct ioat_chan_common *chan); ++dma_addr_t ioat_get_current_completion(struct ioat_chan_common *chan); + void ioat_init_channel(struct ioatdma_device *device, + struct ioat_chan_common *chan, int idx); + enum dma_status ioat_dma_tx_status(struct dma_chan *c, dma_cookie_t cookie, +@@ -341,7 +341,7 @@ + void ioat_dma_unmap(struct ioat_chan_common *chan, enum dma_ctrl_flags flags, + size_t len, struct ioat_dma_descriptor *hw); + bool ioat_cleanup_preamble(struct ioat_chan_common *chan, +- unsigned long *phys_complete); ++ dma_addr_t *phys_complete); + void ioat_kobject_add(struct ioatdma_device *device, struct kobj_type *type); + void ioat_kobject_del(struct ioatdma_device *device); + extern const struct sysfs_ops ioat_sysfs_ops; +diff -u -r -N linux-2.6-3.2.12.orig/drivers/dma/ioat/dma_v2.c linux-2.6-3.2.12/drivers/dma/ioat/dma_v2.c +--- linux-2.6-3.2.12.orig/drivers/dma/ioat/dma_v2.c 2012-03-19 16:03:17.000000000 +0000 ++++ linux-2.6-3.2.12/drivers/dma/ioat/dma_v2.c 2012-03-24 05:55:27.000000000 +0000 +@@ -126,7 +126,7 @@ + spin_unlock_bh(&ioat->prep_lock); + } + +-static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete) ++static void __cleanup(struct ioat2_dma_chan *ioat, dma_addr_t phys_complete) + { + struct ioat_chan_common *chan = &ioat->base; + struct dma_async_tx_descriptor *tx; +@@ -178,7 +178,7 @@ + static void ioat2_cleanup(struct ioat2_dma_chan *ioat) + { + struct ioat_chan_common *chan = &ioat->base; +- unsigned long phys_complete; ++ dma_addr_t phys_complete; + + spin_lock_bh(&chan->cleanup_lock); + if (ioat_cleanup_preamble(chan, &phys_complete)) +@@ -259,7 +259,7 @@ + static void ioat2_restart_channel(struct ioat2_dma_chan *ioat) + { + struct ioat_chan_common *chan = &ioat->base; +- unsigned long phys_complete; ++ dma_addr_t phys_complete; + + ioat2_quiesce(chan, 0); + if (ioat_cleanup_preamble(chan, &phys_complete)) +@@ -274,7 +274,7 @@ + struct ioat_chan_common *chan = &ioat->base; + + if (test_bit(IOAT_COMPLETION_PENDING, &chan->state)) { +- unsigned long phys_complete; ++ dma_addr_t phys_complete; + u64 status; + + status = ioat_chansts(chan); +diff -u -r -N linux-2.6-3.2.12.orig/drivers/dma/ioat/dma_v3.c linux-2.6-3.2.12/drivers/dma/ioat/dma_v3.c +--- linux-2.6-3.2.12.orig/drivers/dma/ioat/dma_v3.c 2012-03-19 16:03:17.000000000 +0000 ++++ linux-2.6-3.2.12/drivers/dma/ioat/dma_v3.c 2012-03-24 05:57:18.000000000 +0000 +@@ -256,7 +256,7 @@ + * The difference from the dma_v2.c __cleanup() is that this routine + * handles extended descriptors and dma-unmapping raid operations. + */ +-static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete) ++static void __cleanup(struct ioat2_dma_chan *ioat, dma_addr_t phys_complete) + { + struct ioat_chan_common *chan = &ioat->base; + struct ioat_ring_ent *desc; +@@ -314,7 +314,7 @@ + static void ioat3_cleanup(struct ioat2_dma_chan *ioat) + { + struct ioat_chan_common *chan = &ioat->base; +- unsigned long phys_complete; ++ dma_addr_t phys_complete; + + spin_lock_bh(&chan->cleanup_lock); + if (ioat_cleanup_preamble(chan, &phys_complete)) +@@ -333,7 +333,7 @@ + static void ioat3_restart_channel(struct ioat2_dma_chan *ioat) + { + struct ioat_chan_common *chan = &ioat->base; +- unsigned long phys_complete; ++ dma_addr_t phys_complete; + + ioat2_quiesce(chan, 0); + if (ioat_cleanup_preamble(chan, &phys_complete)) +@@ -348,7 +348,7 @@ + struct ioat_chan_common *chan = &ioat->base; + + if (test_bit(IOAT_COMPLETION_PENDING, &chan->state)) { +- unsigned long phys_complete; ++ dma_addr_t phys_complete; + u64 status; + + status = ioat_chansts(chan); diff -u -N -r a/debian/patches/series/base b/debian/patches/series/base --- a/debian/patches/series/base 2012-03-24 05:38:19.000000000 +0000 +++ b/debian/patches/series/base 2012-03-24 06:03:22.000000000 +0000 @@ -85,3 +85,4 @@ + bugfix/all/CIFS-Fix-a-spurious-error-in-cifs_push_posix_locks.patch + bugfix/all/tcp-fix-syncookie-regression.patch + bugfix/all/ipv6-don-t-dev_hold-dev-in-ip6_mc_find_dev_rcu.patch ++ bugfix/all/ioat_unsigned_long_to_dma_addr_t.patch