2.6.27.43 stable review
Subsystems (38)
cover 2.6.27.43 stable review
This is the start of the stable review cycle for the 2.6.27.43 release. There are 10 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let us know. If anyone is a maintainer of the proper subsystem, and wants to add a Signed-off-by: line to the patch, please respond with it.
Responses should be made by Thursday, Jan 7, 00:00:00 UTC. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
kernel.org/pub/linux/kernel/v2.6/stable-review/patch-2.6.27.43-rc1.gz
and the diffstat can be found below.
thanks,
greg k-h
Makefile | 2 +- arch/x86/kernel/ptrace.c | 16 ++++++++-------- arch/x86/kvm/mmu.c | 8 ++++++++ drivers/ata/pata_cmd64x.c | 2 +- drivers/i2c/chips/tsl2550.c | 3 +++ drivers/net/wireless/libertas/wext.c | 2 -- drivers/net/wireless/rt2x00/rt61pci.c | 5 +++++ drivers/s390/block/dasd_diag.c | 19 ++++++++++++++++--- fs/namei.c | 1 + include/net/ipv6.h | 7 +++++++ include/net/netfilter/ipv6/nf_conntrack_ipv6.h | 2 +- net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 13 +++++++++++-- net/ipv6/netfilter/nf_conntrack_reasm.c | 7 ++++--- net/ipv6/reassembly.c | 5 ++++- sound/mips/sgio2audio.c | 2 +- sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c | 2 +- sound/usb/usbaudio.c | 2 +- virt/kvm/kvm_main.c | 2 -- 18 files changed, 73 insertions(+), 27 deletions(-)
PATCH 1/10 Libertas: fix buffer overflow in lbs_get_essid()
2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Daniel Mack <[email protected]>
commit 45b241689179a6065384260242637cf21dabfb2d upstream.
The libertas driver copies the SSID buffer back to the wireless core and appends a trailing NULL character for termination. This is
a) unnecessary because the buffer is allocated with kzalloc and is hence already NULLed when this function is called, and
b) for priv->curbssparams.ssid_len == 32, it writes back one byte too much which causes memory corruptions.
Fix this by removing the extra write.
--- drivers/net/wireless/libertas/wext.c | 2 -- 1 file changed, 2 deletions(-)
drivers/net/wireless/libertas/wext.c +0 -2
@@ -1899,10 +1899,8 @@ static int lbs_get_essid(struct net_deviif (priv->connect_status ==LBS_CONNECTED ) {memcpy (extra, priv->curbssparams.ssid, priv->curbssparams.ssid_len); - extra[priv->curbssparams.ssid_len] ='\0' ; }else {memset (extra,0 ,32 ); - extra[priv->curbssparams.ssid_len] ='\0' ; }/* * If none, we may want to get the one that was set
PATCH 2/10 pata_cmd64x: fix overclocking of UDMA0-2 modes
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Bartlomiej Zolnierkiewicz <[email protected]>
commit 509426bd46ad0903dca409803e0ee3d30f99f1e8 upstream.
adev->dma_mode stores the transfer mode value not UDMA mode number so the condition in cmd64x_set_dmamode() is always true and the higher UDMA clock is always selected. This can potentially result in data corruption when UDMA33 device is used, when 40-wire cable is used or when the error recovery code decides to lower the device speed down.
The issue was introduced in the commit 6a40da0 ("libata cmd64x: whack into a shape that looks like the documentation") which goes back to kernel 2.6.20.
--- drivers/ata/pata_cmd64x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/ata/pata_cmd64x.c +1 -1
@@ -219,7 +219,7 @@ static void cmd64x_set_dmamode(struct at regU |= udma_data[adev->dma_mode -XFER_UDMA_0 ] << shift;/* Merge the control bits */ regU |=1 << adev->devno;/* UDMA on */ -if (adev->dma_mode >2 )/* 15nS timing */ +if (adev->dma_mode >XFER_UDMA_2 )/* 15nS timing */ regU |=4 << adev->devno; }else { regU &= ~ (1 << adev->devno);/* UDMA off */
PATCH 3/10 sound: sgio2audio/pdaudiocf/usb-audio: initialize PCM buffer
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Clemens Ladisch <[email protected]>
commit 3e85fd614c7b6bb7f33bb04a0dcb5a3bfca4c0fe upstream.
When allocating the PCM buffer, use vmalloc_user() instead of vmalloc(). Otherwise, it would be possible for applications to play the previous contents of the kernel memory to the speakers, or to read it directly if the buffer is exported to userspace.
--- sound/mips/sgio2audio.c | 2 +- sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c | 2 +- sound/usb/usbaudio.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-)
sound/mips/sgio2audio.c +1 -1
@@ -609,7 +609,7 @@ static int snd_sgio2audio_pcm_hw_params(/* alloc virtual 'dma' area */ if (runtime->dma_area)vfree (runtime->dma_area); - runtime->dma_area =vmalloc (size); + runtime->dma_area =vmalloc_user (size);if (runtime->dma_area ==NULL )return -ENOMEM ; runtime->dma_bytes = size;
sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c +1 -1
@@ -51,7 +51,7 @@ static int snd_pcm_alloc_vmalloc_buffer(return 0 ;/* already enough large */ vfree (runtime->dma_area); } - runtime->dma_area =vmalloc_32 (size); + runtime->dma_area =vmalloc_32_user (size);if (! runtime->dma_area)return -ENOMEM ; runtime->dma_bytes = size;
sound/usb/usbaudio.c +1 -1
@@ -740,7 +740,7 @@ static int snd_pcm_alloc_vmalloc_buffer(return 0 ;/* already large enough */ vfree (runtime->dma_area); } - runtime->dma_area =vmalloc (size); + runtime->dma_area =vmalloc_user (size);if (!runtime->dma_area)return -ENOMEM ; runtime->dma_bytes = size;
PATCH 4/10 i2c/tsl2550: Fix lux value in extended mode
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Michele Jr De Candia <[email protected]>
commit 5f5bfb09d81c9a1d26238ae6668e584c14ae3daf upstream.
According to the TAOS Application Note 'Controlling a Backlight with the TSL2550 Ambient Light Sensor' (page 14), the actual lux value in extended mode should be obtained multiplying the calculated lux value by 5.
--- drivers/i2c/chips/tsl2550.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/i2c/chips/tsl2550.c +3 -0
@@ -277,6 +277,7 @@ static DEVICE_ATTR(operating_mode, S_IWUstatic ssize_t __tsl2550_show_lux (struct i2c_client *client,char *buf) { +struct tsl2550_data *data =i2c_get_clientdata (client);u8 ch0, ch1;int ret;
@@ -296,6 +297,8 @@ static ssize_t __tsl2550_show_lux(struct ret =tsl2550_calculate_lux (ch0, ch1);if (ret <0 )return ret; +if (data->operating_mode ==1 ) + ret *=5 ;return sprintf (buf,"%d\n" , ret); }
PATCH 5/10 ipv6: reassembly: use seperate reassembly queues for conntrack and local delivery
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Patrick McHardy <[email protected]>
commit 0b5ccb2ee250136dd7385b1c7da28417d0d4d32d upstream.
Currently the same reassembly queue might be used for packets reassembled by conntrack in different positions in the stack (PREROUTING/LOCAL_OUT), as well as local delivery. This can cause "packet jumps" when the fragment completing a reassembled packet is queued from a different position in the stack than the previous ones.
Add a "user" identifier to the reassembly queue key to seperate the queues of each caller, similar to what we do for IPv4.
--- include/net/ipv6.h | 7 +++++++ include/net/netfilter/ipv6/nf_conntrack_ipv6.h | 2 +- net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 13 +++++++++++-- net/ipv6/netfilter/nf_conntrack_reasm.c | 7 ++++--- net/ipv6/reassembly.c | 5 ++++- 5 files changed, 27 insertions(+), 7 deletions(-)
include/net/ipv6.h +7 -0
@@ -342,8 +342,15 @@ static inline int ipv6_prefix_equal(consstruct inet_frag_queue ; +enum ip6_defrag_users { +IP6_DEFRAG_LOCAL_DELIVER , +IP6_DEFRAG_CONNTRACK_IN , +IP6_DEFRAG_CONNTRACK_OUT , +}; +struct ip6_create_arg {__be32 id; +u32 user;struct in6_addr *src;struct in6_addr *dst; };
include/net/netfilter/ipv6/nf_conntrack_ipv6.h +1 -1
@@ -9,7 +9,7 @@ extern struct nf_conntrack_l4proto nf_coextern int nf_ct_frag6_init (void );extern void nf_ct_frag6_cleanup (void ); -extern struct sk_buff *nf_ct_frag6_gather (struct sk_buff *skb); +extern struct sk_buff *nf_ct_frag6_gather (struct sk_buff *skb,u32 user); extern void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb, struct net_device *in, struct net_device *out,
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +11 -2
@@ -183,6 +183,16 @@ out:return nf_conntrack_confirm (skb); } +static enum ip6_defrag_users nf_ct6_defrag_user (unsigned int hooknum, +struct sk_buff *skb) +{ +if (hooknum ==NF_INET_PRE_ROUTING ) +return IP6_DEFRAG_CONNTRACK_IN ; +else +return IP6_DEFRAG_CONNTRACK_OUT ; + +} + static unsigned int ipv6_defrag(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in,
@@ -195,8 +205,7 @@ static unsigned int ipv6_defrag(unsignedif (skb->nfct)return NF_ACCEPT ; - reasm =nf_ct_frag6_gather (skb); - + reasm =nf_ct_frag6_gather (skb,nf_ct6_defrag_user (hooknum, skb));/* queued */ if (reasm ==NULL )return NF_STOLEN ;
net/ipv6/netfilter/nf_conntrack_reasm.c +4 -3
@@ -198,13 +198,14 @@ out:/* Creation primitives. */ static __inline__struct nf_ct_frag6_queue * -fq_find (__be32 id,struct in6_addr *src,struct in6_addr *dst) +fq_find (__be32 id,u32 user,struct in6_addr *src,struct in6_addr *dst) {struct inet_frag_queue *q;struct ip6_create_arg arg;unsigned int hash; arg.id = id; + arg.user = user; arg.src = src; arg.dst = dst;
@@ -589,7 +590,7 @@ find_prev_fhdr(struct sk_buff *skb, u8 *return 0 ; } -struct sk_buff *nf_ct_frag6_gather (struct sk_buff *skb) +struct sk_buff *nf_ct_frag6_gather (struct sk_buff *skb,u32 user) {struct sk_buff *clone;struct net_device *dev = skb->dev;
@@ -635,7 +636,7 @@ struct sk_buff *nf_ct_frag6_gather(strucif (atomic_read (&nf_init_frags.mem) > nf_init_frags.high_thresh)nf_ct_frag6_evictor (); - fq =fq_find (fhdr->identification, &hdr->saddr, &hdr->daddr); + fq =fq_find (fhdr->identification, user, &hdr->saddr, &hdr->daddr);if (fq ==NULL ) {pr_debug ("Can't find and can't create new queue\n" ); goto ret_orig;
net/ipv6/reassembly.c +4 -1
@@ -72,6 +72,7 @@ struct frag_queuestruct inet_frag_queue q;__be32 id;/* fragment id */ +u32 user;struct in6_addr saddr;struct in6_addr daddr;
@@ -140,7 +141,7 @@ int ip6_frag_match(struct inet_frag_queustruct ip6_create_arg *arg = a; fq = container_of(q, struct frag_queue, q); -return (fq->id == arg->id && +return (fq->id == arg->id && fq->user == arg->user &&ipv6_addr_equal (&fq->saddr, arg->src) &&ipv6_addr_equal (&fq->daddr, arg->dst)); }
@@ -162,6 +163,7 @@ void ip6_frag_init(struct inet_frag_queustruct ip6_create_arg *arg = a; fq->id = arg->id; + fq->user = arg->user;ipv6_addr_copy (&fq->saddr, arg->src);ipv6_addr_copy (&fq->daddr, arg->dst); }
@@ -243,6 +245,7 @@ fq_find(struct net *net, __be32 id, struunsigned int hash; arg.id = id; + arg.user =IP6_DEFRAG_LOCAL_DELIVER ; arg.src = src; arg.dst = dst;
PATCH 6/10 S390: dasd: support DIAG access for read-only devices
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Stefan Weinhuber <[email protected]>
commit 22825ab7693fd29769518a0d25ba43c01a50092a upstream.
When a DASD device is used with the DIAG discipline, the DIAG initialization will indicate success or error with a respective return code. So far we have interpreted a return code of 4 as error, but it actually means that the initialization was successful, but the device is read-only. To allow read-only devices to be used with DIAG we need to accept a return code of 4 as success.
Re-initialization of the DIAG access is also part of the DIAG error recovery. If we find that the access mode of a device has been changed from writable to read-only while the device was in use, we print an error message.
--- drivers/s390/block/dasd_diag.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-)
drivers/s390/block/dasd_diag.c +16 -3
@@ -143,6 +143,15 @@ dasd_diag_erp(struct dasd_device *devicemdsk_term_io (device); rc =mdsk_init_io (device, device->block->bp_block,0 ,NULL ); +if (rc ==4 ) { +if (!(device->features &DASD_FEATURE_READONLY )) { +dev_warn (&device->cdev->dev, +"The access mode of a DIAG device changed" +" to read-only" ); + device->features |=DASD_FEATURE_READONLY ; + } + rc =0 ; + }if (rc)DEV_MESSAGE (KERN_WARNING , device,"DIAG ERP unsuccessful, " "rc=%d" , rc);
@@ -432,16 +441,20 @@ dasd_diag_check_device(struct dasd_devicfor (sb =512 ; sb < bsize; sb = sb <<1 ) block->s2b_shift++; rc =mdsk_init_io (device, block->bp_block,0 ,NULL ); -if (rc) { +if (rc && (rc !=4 )) {DEV_MESSAGE (KERN_WARNING , device,"DIAG initialization " "failed (rc=%d)" , rc); rc = -EIO ; }else { +if (rc ==4 ) + device->features |=DASD_FEATURE_READONLY ;DEV_MESSAGE (KERN_INFO , device, -"(%ld B/blk): %ldkB" , +"(%ld B/blk): %ldkB%s" , (unsigned long ) block->bp_block, (unsigned long ) (block->blocks << - block->s2b_shift) >>1 ); + block->s2b_shift) >>1 , + (rc ==4 ) ?", read-only device" :"" ); + rc =0 ; } out_label:free_page ((long ) label);
PATCH 7/10 x86/ptrace: make genregs[32]_get/set more robust
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Linus Torvalds <[email protected]>
commit 04a1e62c2cec820501f93526ad1e46073b802dc4 upstream.
The loop condition is fragile: we compare an unsigned value to zero, and then decrement it by something larger than one in the loop. All the callers should be passing in appropriately aligned buffer lengths, but it's better to just not rely on it, and have some appropriate defensive loop limits.
--- arch/x86/kernel/ptrace.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
arch/x86/kernel/ptrace.c +8 -8
@@ -416,14 +416,14 @@ static int genregs_get(struct task_struc {if (kbuf) {unsigned long *k = kbuf; -while (count >0 ) { +while (count >=sizeof (*k)) { *k++ =getreg (target, pos); count -=sizeof (*k); pos +=sizeof (*k); } }else {unsigned long __user *u = ubuf; -while (count >0 ) { +while (count >=sizeof (*u)) {if (__put_user (getreg (target, pos), u++))return -EFAULT ; count -=sizeof (*u);
@@ -442,14 +442,14 @@ static int genregs_set(struct task_strucint ret =0 ;if (kbuf) {const unsigned long *k = kbuf; -while (count >0 && !ret) { +while (count >=sizeof (*k) && !ret) { ret =putreg (target, pos, *k++); count -=sizeof (*k); pos +=sizeof (*k); } }else {const unsigned long __user *u = ubuf; -while (count >0 && !ret) { +while (count >=sizeof (*u) && !ret) {unsigned long word; ret =__get_user (word, u++);if (ret)
@@ -1159,14 +1159,14 @@ static int genregs32_get(struct task_str {if (kbuf) {compat_ulong_t *k = kbuf; -while (count >0 ) { +while (count >=sizeof (*k)) {getreg32 (target, pos, k++); count -=sizeof (*k); pos +=sizeof (*k); } }else {compat_ulong_t __user *u = ubuf; -while (count >0 ) { +while (count >=sizeof (*u)) {compat_ulong_t word;getreg32 (target, pos, &word);if (__put_user (word, u++))
@@ -1187,14 +1187,14 @@ static int genregs32_set(struct task_strint ret =0 ;if (kbuf) {const compat_ulong_t *k = kbuf; -while (count >0 && !ret) { +while (count >=sizeof (*k) && !ret) { ret =putreg32 (target, pos, *k++); count -=sizeof (*k); pos +=sizeof (*k); } }else {const compat_ulong_t __user *u = ubuf; -while (count >0 && !ret) { +while (count >=sizeof (*u) && !ret) {compat_ulong_t word; ret =__get_user (word, u++);if (ret)
PATCH 8/10 rt2x00: Disable powersaving for rt61pci and rt2800pci.
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Gertjan van Wingerde <[email protected]>
commit 93b6bd26b74efe46b4579592560f9f1cb7b61994 upstream.
We've had many reports of rt61pci failures with powersaving enabled. Therefore, as a stop-gap measure, disable powersaving of the rt61pci until we have found a proper solution.
Also disable powersaving on rt2800pci as it most probably will show the same problem.
--- drivers/net/wireless/rt2x00/rt61pci.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/net/wireless/rt2x00/rt61pci.c +5 -0
@@ -2281,6 +2281,11 @@ static void rt61pci_probe_hw_mode(structunsigned int i;/* +* Disable powersaving as default. +*/ + rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT ; + +/* * Initialize all hw fields. */ rt2x00dev->hw->flags =
Re: [08/10] rt2x00: Disable powersaving for rt61pci and rt2800pci.
Quoted 29 lines · Greg KH
2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Gertjan van Wingerde <[email protected]>commit
93b6bd26b74efe46b4579592560f9f1cb7b61994upstream.We've had many reports of rt61pci failures with powersaving enabled. Therefore, as a stop-gap measure, disable powersaving of the rt61pci until we have found a proper solution.
Also disable powersaving on rt2800pci as it most probably will show the same problem.Signed-off-by Gertjan van Wingerde <[email protected]>Acked-by Ivo van Doorn <[email protected]>Signed-off-by John W. Linville <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- drivers/net/wireless/rt2x00/rt61pci.c | 5 +++++ 1 file changed, 5 insertions(+)drivers/net/wireless/rt2x00/rt61pci.c +0
-0@@ -2281,6 +2281,11 @@ static void rt61pci_probe_hw_mode(structunsigned int i;
drivers/net/wireless/rt2x00/rt61pci.c static void rt61pci_probe_hw_mode(struct · line 2291
Quoted 10 lines
drivers/net/wireless/rt2x00/rt61pci.c +5
-0/* +* Disable powersaving as default. +*/ + rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT ; + +/* * Initialize all hw fields. */ rt2x00dev->hw->flags =
This one isn't applicable for .27. Powersaving wasn't implemented on .27 yet, so this patch is unnecessary, and won't compile on .27.
---
Gertjan.
Re: [08/10] rt2x00: Disable powersaving for rt61pci and rt2800pci.
Quoted 28 lines · Gertjan van Wingerde
Quoted 27 lines · Greg KH
2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Gertjan van Wingerde <[email protected]>commit
93b6bd26b74efe46b4579592560f9f1cb7b61994upstream.We've had many reports of rt61pci failures with powersaving enabled. Therefore, as a stop-gap measure, disable powersaving of the rt61pci until we have found a proper solution.
Also disable powersaving on rt2800pci as it most probably will show the same problem.Signed-off-by Gertjan van Wingerde <[email protected]>Acked-by Ivo van Doorn <[email protected]>Signed-off-by John W. Linville <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- drivers/net/wireless/rt2x00/rt61pci.c | 5 +++++ 1 file changed, 5 insertions(+)drivers/net/wireless/rt2x00/rt61pci.c +0
-0@@ -2281,6 +2281,11 @@ static void rt61pci_probe_hw_mode(structunsigned int i;
Quoted 15 lines
drivers/net/wireless/rt2x00/rt61pci.c static void rt61pci_probe_hw_mode(struct · line 2291
Quoted 12 lines
drivers/net/wireless/rt2x00/rt61pci.c +5
-0/* +* Disable powersaving as default. +*/ + rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT ; + +/* * Initialize all hw fields. */ rt2x00dev->hw->flags =This one isn't applicable for .27. Powersaving wasn't implemented on .27 yet, so this patch is unnecessary, and won't compile on .27.
Thanks, I've now dropped it.
greg k-h
PATCH 9/10 generic_permission: MAY_OPEN is not write access
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
From: Serge E. Hallyn <[email protected]>
commit 7ea6600148c265b1fd53e521022b1d7aec81d974 upstream.
generic_permission was refusing CAP_DAC_READ_SEARCH-enabled processes from opening DAC-protected files read-only, because do_filp_open adds MAY_OPEN to the open mask.
Ignore MAY_OPEN. After this patch, CAP_DAC_READ_SEARCH is again sufficient to open(fname, O_RDONLY) on a file to which DAC otherwise refuses us read permission.
--- fs/namei.c | 1 + 1 file changed, 1 insertion(+)
fs/namei.c +1 -0
@@ -220,6 +220,7 @@ int generic_permission(struct inode *ino/* * Searching includes executable on directories, else just read. */ + mask &=MAY_READ |MAY_WRITE |MAY_EXEC ;if (mask ==MAY_READ || (S_ISDIR (inode->i_mode) && !(mask &MAY_WRITE )))if (capable (CAP_DAC_READ_SEARCH ))return 0 ;
PATCH 10/10 Revert: KVM: MMU: do not free active mmu pages in free_mmu_pages()
In reply to Greg KH2.6.27-stable review patch. If anyone has any objections, please let us know.
------------------
This reverts the commit d2127c8300fb1ec54af56faee17170e7a525326d, which was the commit f00be0cae4e6ad0a8c7be381c6d9be3586800b3e upstream.
This was done based on comments saying it was causing problems.
--- arch/x86/kvm/mmu.c | 8 ++++++++ virt/kvm/kvm_main.c | 2 -- 2 files changed, 8 insertions(+), 2 deletions(-)
arch/x86/kvm/mmu.c +8 -0
@@ -1995,6 +1995,14 @@ EXPORT_SYMBOL_GPL(kvm_disable_tdp);static void free_mmu_pages (struct kvm_vcpu *vcpu) { +struct kvm_mmu_page *sp; + +while (!list_empty (&vcpu->kvm->arch.active_mmu_pages)) { + sp =container_of (vcpu->kvm->arch.active_mmu_pages.next, + struct kvm_mmu_page, link); +kvm_mmu_zap_page (vcpu->kvm, sp); +cond_resched (); + }free_page ((unsigned long )vcpu->arch.mmu.pae_root); }
virt/kvm/kvm_main.c +0 -2
@@ -406,8 +406,6 @@ static void kvm_destroy_vm(struct kvm *k#endif #if defined(CONFIG_MMU_NOTIFIER ) && defined(KVM_ARCH_WANT_MMU_NOTIFIER )mmu_notifier_unregister (&kvm->mmu_notifier, kvm->mm); -#else -kvm_arch_flush_shadow (kvm);#endif kvm_arch_destroy_vm (kvm);mmdrop (mm);
PATCH 1/39 acerhdf: limit modalias matching to supported
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Stefan Bader <[email protected]>
commit bdc731bc5fcd1794e9ac8ac80c389d302381c123 upstream.
The module alias currently matches any Acer computer but when loaded the BIOS checks will only succeed on Aspire One models. This causes a invalid BIOS warning for all other models (seen on Aspire 4810T). This is not fatal but worries users that see this message. Limiting the moule alias to models starting with AOA or DOA for Packard Bell.
--- drivers/platform/x86/acerhdf.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/platform/x86/acerhdf.c +4 -3
@@ -633,9 +633,10 @@ static void __exit acerhdf_exit(void)MODULE_LICENSE ("GPL" );MODULE_AUTHOR ("Peter Feuerer" );MODULE_DESCRIPTION ("Aspire One temperature and fan driver" ); -MODULE_ALIAS ("dmi:*:*Acer*:*:" ); -MODULE_ALIAS ("dmi:*:*Gateway*:*:" ); -MODULE_ALIAS ("dmi:*:*Packard Bell*:*:" ); +MODULE_ALIAS ("dmi:*:*Acer*:pnAOA*:" ); +MODULE_ALIAS ("dmi:*:*Gateway*:pnAOA*:" ); +MODULE_ALIAS ("dmi:*:*Packard Bell*:pnAOA*:" ); +MODULE_ALIAS ("dmi:*:*Packard Bell*:pnDOA*:" );module_init (acerhdf_init);module_exit (acerhdf_exit);
PATCH 2/39 ASoC: Do not write to invalid registers on the wm9712.
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Eric Millbrandt <[email protected]>
commit 48e3cbb3f67a27d9c2db075f3d0f700246c40caa upstream.
This patch fixes a bug where "virtual" registers were being written to the ac97 bus. This was causing unrelated registers to become corrupted (headphone 0x04, touchscreen 0x78, etc).
This patch duplicates protection that was included in the wm9713 driver.
--- sound/soc/codecs/wm9712.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
sound/soc/codecs/wm9712.c +2 -1
@@ -464,7 +464,8 @@ static int ac97_write(struct snd_soc_cod {u16 *cache = codec->reg_cache; - soc_ac97_ops.write (codec->ac97, reg, val); +if (reg <0x7c ) + soc_ac97_ops.write (codec->ac97, reg, val); reg = reg >>1 ;if (reg < (ARRAY_SIZE (wm9712_reg))) cache[reg] = val;
PATCH 3/39 cifs: NULL out tcon, pSesInfo, and srvTcp pointers when chasing DFS referrals
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Jeff Layton <[email protected]>
commit a2934c7b363ddcc001964f2444649f909e583bef upstream.
The scenario is this:
The kernel gets EREMOTE and starts chasing a DFS referral at mount time. The tcon reference is put, which puts the session reference too, but neither pointer is zeroed out.
The mount gets retried (goto try_mount_again) with new mount info. Session setup fails fails and rc ends up being non-zero. The code then falls through to the end and tries to put the previously freed tcon pointer again. Oops at: cifs_put_smb_ses+0x14/0xd0
Fix this by moving the initialization of the rc variable and the tcon, pSesInfo and srvTcp pointers below the try_mount_again label. Also, add a FreeXid() before the goto to prevent xid "leaks".
--- fs/cifs/connect.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
fs/cifs/connect.c +9 -4
@@ -2267,12 +2267,12 @@ int cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, char *mount_data_global, const char *devname) { - int rc = 0; + int rc;int xid;struct smb_vol *volume_info; -struct cifsSesInfo *pSesInfo =NULL ; -struct cifsTconInfo *tcon =NULL ; -struct TCP_Server_Info *srvTcp =NULL ; +struct cifsSesInfo *pSesInfo; +struct cifsTconInfo *tcon; +struct TCP_Server_Info *srvTcp;char *full_path;char *mount_data = mount_data_global;#ifdef CONFIG_CIFS_DFS_UPCALL
@@ -2281,6 +2281,10 @@ cifs_mount(struct super_block *sb, strucint referral_walks_count =0 ; try_mount_again:#endif + rc =0 ; + tcon =NULL ; + pSesInfo =NULL ; + srvTcp =NULL ; full_path =NULL ; xid =GetXid ();
@@ -2577,6 +2581,7 @@ remote_path_check:cleanup_volume_info (&volume_info); referral_walks_count++; +FreeXid (xid); goto try_mount_again; }#else /* No DFS support, return error on mount */
PATCH 4/39 clockevents: Prevent clockevent_devices list corruption on cpu hotplug
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Thomas Gleixner <[email protected]>
commit bb6eddf7676e1c1f3e637aa93c5224488d99036f upstream.
Xiaotian Feng triggered a list corruption in the clock events list on CPU hotplug and debugged the root cause.
If a CPU registers more than one per cpu clock event device, then only the active clock event device is removed on CPU_DEAD. The unused devices are kept in the clock events device list.
On CPU up the clock event devices are registered again, which means that we list_add an already enqueued list_head. That results in list corruption.
Resolve this by removing all devices which are associated to the dead CPU on CPU_DEAD.
--- kernel/time/clockevents.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)
kernel/time/clockevents.c +15 -3
@@ -237,8 +237,9 @@ void clockevents_exchange_device(struct*/ void clockevents_notify (unsigned long reason,void *arg) { -struct list_head *node, *tmp; +struct clock_event_device *dev, *tmp;unsigned long flags; +int cpu;spin_lock_irqsave (&clockevents_lock, flags);clockevents_do_notify (reason, arg);
@@ -249,8 +250,19 @@ void clockevents_notify(unsigned long re* Unregister the clock event devices which were * released from the users in the notify chain. */ -list_for_each_safe (node, tmp, &clockevents_released) -list_del (node); +list_for_each_entry_safe (dev, tmp, &clockevents_released, list) +list_del (&dev->list); +/* +* Now check whether the CPU has left unused per cpu devices +*/ + cpu = *((int *)arg); +list_for_each_entry_safe (dev, tmp, &clockevent_devices, list) { +if (cpumask_test_cpu (cpu, dev->cpumask) && +cpumask_weight (dev->cpumask) ==1 ) { +BUG_ON (dev->mode !=CLOCK_EVT_MODE_UNUSED ); +list_del (&dev->list); + } + }break ;default :break ;
PATCH 5/39 dma: at_hdmac: correct incompatible type for argument 1 of spin_lock_bh
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Nicolas Ferre <[email protected]>
commit 4297a462f455e38f08976df7b16c849614a287da upstream.
Correct a typo error in locking calls.
--- drivers/dma/at_hdmac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/dma/at_hdmac.c +2 -2
@@ -813,7 +813,7 @@ atc_is_tx_complete(struct dma_chan *chandev_vdbg (chan2dev (chan),"is_tx_complete: %d (d%d, u%d)\n" , cookie, done ? *done :0 , used ? *used :0 ); -spin_lock_bh (atchan->lock); +spin_lock_bh (&atchan->lock); last_complete = atchan->completed_cookie; last_used = chan->cookie;
@@ -828,7 +828,7 @@ atc_is_tx_complete(struct dma_chan *chan ret =dma_async_is_complete (cookie, last_complete, last_used); } -spin_unlock_bh (atchan->lock); +spin_unlock_bh (&atchan->lock);if (done) *done = last_complete;
PATCH 6/39 drivers/net/usb: Correct code taking the size of a pointer
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Julia Lawall <[email protected]>
commit 6057912d7baad31be9819518674ffad349a065b1 upstream.
sizeof(dev->dev_addr) is the size of a pointer. A few lines above, the size of this field is obtained using netdev->addr_len for a call to memcpy, so do the same here.
A simplified version of the semantic patch that finds this problem is as
follows: (http://coccinelle.lip6.fr/)
// <smpl>
@@
expression *x;
expression f;
type T;
@@
*f(...,(T)x,...)
// </smpl>
--- drivers/net/usb/rtl8150.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/usb/rtl8150.c +1 -1
@@ -324,7 +324,7 @@ static int rtl8150_set_mac_address(strucdbg ("%02X:" , netdev->dev_addr[i]);dbg ("%02X\n" , netdev->dev_addr[i]);/* Set the IDR registers. */ -set_registers (dev,IDR ,sizeof (netdev->dev_addr), netdev->dev_addr); +set_registers (dev,IDR , netdev->addr_len, netdev->dev_addr);#ifdef EEPROM_WRITE {u8 cr;
PATCH 7/39 iwmc3200wifi: fix array out-of-boundary access
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Zhu Yi <[email protected]>
commit 6c853da3f30c93eae847ecbcd9fdf10ba0da04c2 upstream.
Allocate priv->rx_packets[IWM_RX_ID_HASH + 1] because the max array index is IWM_RX_ID_HASH according to IWM_RX_ID_GET_HASH().
--- drivers/net/wireless/iwmc3200wifi/iwm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/iwmc3200wifi/iwm.h +1 -1
@@ -268,7 +268,7 @@ struct iwm_priv {struct sk_buff_head rx_list;struct list_head rx_tickets; -struct list_head rx_packets[IWM_RX_ID_HASH ]; +struct list_head rx_packets[IWM_RX_ID_HASH +1 ];struct workqueue_struct *rx_wq;struct work_struct rx_worker;
Re: [07/39] iwmc3200wifi: fix array out-of-boundary access
Quoted 1 line · Greg KH
2.6.31-stable review patch. If anyone has any objections, please let us know.
Greg, please ignore this. It is false alarm and not required for stable. Sorry for the noise.
Thanks,
-yi
Quoted 28 lines
From: Zhu Yi <[email protected]>
commit
6c853da3f30c93eae847ecbcd9fdf10ba0da04c2upstream.Allocate priv->rx_packets[IWM_RX_ID_HASH + 1] because the max array index is
IWM_RX_ID_HASHaccording toIWM_RX_ID_GET_HASH().Signed-off-by Zhu Yi <[email protected]>Signed-off-by John W. Linville <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- drivers/net/wireless/iwmc3200wifi/iwm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)drivers/net/wireless/iwmc3200wifi/iwm.h +1
-1@@ -268,7 +268,7 @@ struct iwm_priv {struct sk_buff_head rx_list;struct list_head rx_tickets; -struct list_head rx_packets[IWM_RX_ID_HASH ]; +struct list_head rx_packets[IWM_RX_ID_HASH +1 ];struct workqueue_struct *rx_wq;struct work_struct rx_worker;
Re: [07/39] iwmc3200wifi: fix array out-of-boundary access
Quoted 5 lines · Zhu Yi
Quoted 1 line · Greg KH
2.6.31-stable review patch. If anyone has any objections, please let us know.
Greg, please ignore this. It is false alarm and not required for stable. Sorry for the noise.
Should I also drop it from the .32-stable tree as well?
thanks,
greg k-h
Re: [stable] [07/39] iwmc3200wifi: fix array out-of-boundary access
Quoted 8 lines · Greg KH
Quoted 5 lines · Zhu Yi
Quoted 1 line · Greg KH
2.6.31-stable review patch. If anyone has any objections, please let us know.
Greg, please ignore this. It is false alarm and not required for stable. Sorry for the noise.
Should I also drop it from the .32-stable tree as well?
I've dropped it for now to be safe.
thanks,
greg k-h
PATCH 8/39 Libertas: fix buffer overflow in lbs_get_essid()
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Daniel Mack <[email protected]>
commit 45b241689179a6065384260242637cf21dabfb2d upstream.
The libertas driver copies the SSID buffer back to the wireless core and appends a trailing NULL character for termination. This is
a) unnecessary because the buffer is allocated with kzalloc and is hence already NULLed when this function is called, and
b) for priv->curbssparams.ssid_len == 32, it writes back one byte too much which causes memory corruptions.
Fix this by removing the extra write.
--- drivers/net/wireless/libertas/wext.c | 2 -- 1 file changed, 2 deletions(-)
drivers/net/wireless/libertas/wext.c +0 -2
@@ -1951,10 +1951,8 @@ static int lbs_get_essid(struct net_deviif (priv->connect_status ==LBS_CONNECTED ) {memcpy (extra, priv->curbssparams.ssid, priv->curbssparams.ssid_len); - extra[priv->curbssparams.ssid_len] ='\0' ; }else {memset (extra,0 ,32 ); - extra[priv->curbssparams.ssid_len] ='\0' ; }/* * If none, we may want to get the one that was set
PATCH 9/39 md: Fix unfortunate interaction with evms
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: NeilBrown <[email protected]>
commit cbd1998377504df005302ac90d49db72a48552a6 upstream.
evms configures md arrays by:
open device
send ioctl
close device
for each different ioctl needed.
Since 2.6.29, the device can disappear after the 'close' unless a significant configuration has happened to the device. The change made by "SET_ARRAY_INFO" can too minor to stop the device from disappearing, but important enough that losing the change is bad.
So: make sure SET_ARRAY_INFO sets mddev->ctime, and keep the device active as long as ctime is non-zero (it gets zeroed with lots of other things when the array is stopped).
This is suitable for -stable kernels since 2.6.29.
--- drivers/md/md.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/md/md.c +7 -1
@@ -276,7 +276,9 @@ static void mddev_put(mddev_t *mddev)if (!atomic_dec_and_lock (&mddev->active, &all_mddevs_lock))return ;if (!mddev->raid_disks &&list_empty (&mddev->disks) && - !mddev->hold_active) { + mddev->ctime ==0 && !mddev->hold_active) { +/* Array is not configured at all, and not held active, +* so destroy it */ list_del (&mddev->all_mddevs);if (mddev->gendisk) {/* we did a probe so need to clean up.
@@ -5040,6 +5042,10 @@ static int set_array_info(mddev_t * mdde mddev->minor_version = info->minor_version; mddev->patch_version = info->patch_version; mddev->persistent = !info->not_persistent; +/* ensure mddev_put doesn't delete this now that there +* is some minimal configuration. +*/ + mddev->ctime =get_seconds ();return 0 ; } mddev->major_version =MD_MAJOR_VERSION ;
PATCH 10/39 pata_cmd64x: fix overclocking of UDMA0-2 modes
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Bartlomiej Zolnierkiewicz <[email protected]>
commit 509426bd46ad0903dca409803e0ee3d30f99f1e8 upstream.
adev->dma_mode stores the transfer mode value not UDMA mode number so the condition in cmd64x_set_dmamode() is always true and the higher UDMA clock is always selected. This can potentially result in data corruption when UDMA33 device is used, when 40-wire cable is used or when the error recovery code decides to lower the device speed down.
The issue was introduced in the commit 6a40da0 ("libata cmd64x: whack into a shape that looks like the documentation") which goes back to kernel 2.6.20.
--- drivers/ata/pata_cmd64x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/ata/pata_cmd64x.c +1 -1
@@ -219,7 +219,7 @@ static void cmd64x_set_dmamode(struct at regU |= udma_data[adev->dma_mode -XFER_UDMA_0 ] << shift;/* Merge the control bits */ regU |=1 << adev->devno;/* UDMA on */ -if (adev->dma_mode >2 )/* 15nS timing */ +if (adev->dma_mode >XFER_UDMA_2 )/* 15nS timing */ regU |=4 << adev->devno; }else { regU &= ~ (1 << adev->devno);/* UDMA off */
PATCH 11/39 pata_hpt3x2n: fix clock turnaround
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Sergei Shtylyov <[email protected]>
commit 256ace9bbd4cdb6d48d5f55d55d42fa20527fad1 upstream.
The clock turnaround code still doesn't work for several reasons:
- 'USE_DPLL' flag in 'ap->host->private_data' is never initialized or updated, so the driver can only set the chip to the DPLL clock mode, not the PCI mode;
- the driver doesn't serialize access to the channels depending on the current clock mode like the vendor drivers, so the clock turnaround is only executed "optionally", not always as it should be;
- the wrong ports are written to when hpt3x2n_set_clock() is called for the secondary channel;
- hpt3x2n_set_clock() can inadvertently enable the disabled channels when resetting the channel state machines.
--- drivers/ata/pata_hpt3x2n.c | 64 ++++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 29 deletions(-)
drivers/ata/pata_hpt3x2n.c +35 -29
@@ -8,7 +8,7 @@* Copyright (C) 1999-2003 Andre Hedrick <[email protected]> * Portions Copyright (C) 2001 Sun Microsystems, Inc. * Portions Copyright (C) 2003 Red Hat Inc -* Portions Copyright (C) 2005-2007 MontaVista Software, Inc. +* Portions Copyright (C) 2005-2009 MontaVista Software, Inc. * * * TODO
@@ -25,7 +25,7 @@#include <linux/libata.h> #define DRV_NAME "pata_hpt3x2n" -#define DRV_VERSION "0.3.7" +#define DRV_VERSION "0.3.8"enum {HPT_PCI_FAST = (1 <<31 ),
@@ -262,7 +262,7 @@ static void hpt3x2n_bmdma_stop(struct atstatic void hpt3x2n_set_clock (struct ata_port *ap,int source) { -void __iomem *bmdma = ap->ioaddr.bmdma_addr; +void __iomem *bmdma = ap->ioaddr.bmdma_addr - ap->port_no *8 ;/* Tristate the bus */ iowrite8 (0x80 , bmdma+0x73 );
@@ -272,9 +272,9 @@ static void hpt3x2n_set_clock(struct ataiowrite8 (source, bmdma+0x7B );iowrite8 (0xC0 , bmdma+0x79 ); -/* Reset state machines */ -iowrite8 (0x37 , bmdma+0x70 ); -iowrite8 (0x37 , bmdma+0x74 ); +/* Reset state machines, avoid enabling the disabled channels */ +iowrite8 (ioread8 (bmdma+0x70 ) |0x32 , bmdma+0x70 ); +iowrite8 (ioread8 (bmdma+0x74 ) |0x32 , bmdma+0x74 );/* Complete reset */ iowrite8 (0x00 , bmdma+0x79 );
@@ -284,21 +284,10 @@ static void hpt3x2n_set_clock(struct ataiowrite8 (0x00 , bmdma+0x77 ); } -/* Check if our partner interface is busy */ - -static int hpt3x2n_pair_idle (struct ata_port *ap) -{ -struct ata_host *host = ap->host; -struct ata_port *pair = host->ports[ap->port_no ^1 ]; - -if (pair->hsm_task_state ==HSM_ST_IDLE ) -return 1 ; -return 0 ; -} -static int hpt3x2n_use_dpll (struct ata_port *ap,int writing) {long flags = (long )ap->host->private_data; +/* See if we should use the DPLL */ if (writing)return USE_DPLL ;/* Needed for write */
@@ -307,20 +296,35 @@ static int hpt3x2n_use_dpll(struct ata_preturn 0 ; } +static int hpt3x2n_qc_defer (struct ata_queued_cmd *qc) +{ +struct ata_port *ap = qc->ap; +struct ata_port *alt = ap->host->ports[ap->port_no ^1 ]; +int rc, flags = (long )ap->host->private_data; +int dpll =hpt3x2n_use_dpll (ap, qc->tf.flags &ATA_TFLAG_WRITE ); + +/* First apply the usual rules */ + rc =ata_std_qc_defer (qc); +if (rc !=0 ) +return rc; + +if ((flags &USE_DPLL ) != dpll && alt->qc_active) +return ATA_DEFER_PORT ; +return 0 ; +} +static unsigned int hpt3x2n_qc_issue (struct ata_queued_cmd *qc) { -struct ata_taskfile *tf = &qc->tf;struct ata_port *ap = qc->ap;int flags = (long )ap->host->private_data; +int dpll =hpt3x2n_use_dpll (ap, qc->tf.flags &ATA_TFLAG_WRITE ); -if (hpt3x2n_pair_idle (ap)) { -int dpll =hpt3x2n_use_dpll (ap, (tf->flags &ATA_TFLAG_WRITE )); -if ((flags &USE_DPLL ) != dpll) { -if (dpll ==1 ) -hpt3x2n_set_clock (ap,0x21 ); -else -hpt3x2n_set_clock (ap,0x23 ); - } +if ((flags &USE_DPLL ) != dpll) { + flags &= ~USE_DPLL ; + flags |= dpll; + ap->host->private_data = (void *)(long )flags; + +hpt3x2n_set_clock (ap, dpll ?0x21 :0x23 ); }return ata_sff_qc_issue (qc); }
@@ -337,6 +341,8 @@ static struct ata_port_operations hpt3x2 .inherits = &ata_bmdma_port_ops, .bmdma_stop = hpt3x2n_bmdma_stop, + + .qc_defer = hpt3x2n_qc_defer, .qc_issue = hpt3x2n_qc_issue, .cable_detect = hpt3x2n_cable_detect,
@@ -454,7 +460,7 @@ static int hpt3x2n_init_one(struct pci_dunsigned int f_low, f_high;int adjust;unsigned long iobase =pci_resource_start (dev,4 ); -void *hpriv =NULL ; +void *hpriv = (void *)USE_DPLL ;int rc; rc =pcim_enable_device (dev);
@@ -542,7 +548,7 @@ static int hpt3x2n_init_one(struct pci_d/* Set our private data up. We only need a few flags so we use it directly */ if (pci_mhz >60 ) { - hpriv = (void *)PCI66 ; + hpriv = (void *)(PCI66 |USE_DPLL );/* * On HPT371N, if ATA clock is 66 MHz we must set bit 2 in * the MISC. register to stretch the UltraDMA Tss timing.
PATCH 12/39 SCSI: fc class: fix fc_transport_init error handling
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Mike Christie <[email protected]>
commit 48de68a40aef032a2e198437f4781a83bfb938db upstream.
If transport_class_register fails we should unregister any registered classes, or we will leak memory or other resources.
I did a quick modprobe of scsi_transport_fc to test the patch.
--- drivers/scsi/scsi_transport_fc.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-)
drivers/scsi/scsi_transport_fc.c +14 -3
@@ -648,11 +648,22 @@ static __init int fc_transport_init(voidreturn error; error =transport_class_register (&fc_vport_class);if (error) -return error; + goto unreg_host_class; error =transport_class_register (&fc_rport_class);if (error) -return error; -return transport_class_register (&fc_transport_class); + goto unreg_vport_class; + error =transport_class_register (&fc_transport_class); +if (error) + goto unreg_rport_class; +return 0 ; + +unreg_rport_class: +transport_class_unregister (&fc_rport_class); +unreg_vport_class: +transport_class_unregister (&fc_vport_class); +unreg_host_class: +transport_class_unregister (&fc_host_class); +return error; } static void __exit fc_transport_exit(void)
PATCH 13/39 sound: sgio2audio/pdaudiocf/usb-audio: initialize PCM buffer
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Clemens Ladisch <[email protected]>
commit 3e85fd614c7b6bb7f33bb04a0dcb5a3bfca4c0fe upstream.
When allocating the PCM buffer, use vmalloc_user() instead of vmalloc(). Otherwise, it would be possible for applications to play the previous contents of the kernel memory to the speakers, or to read it directly if the buffer is exported to userspace.
--- sound/mips/sgio2audio.c | 2 +- sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c | 2 +- sound/usb/usbaudio.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-)
sound/mips/sgio2audio.c +1 -1
@@ -609,7 +609,7 @@ static int snd_sgio2audio_pcm_hw_params(/* alloc virtual 'dma' area */ if (runtime->dma_area)vfree (runtime->dma_area); - runtime->dma_area =vmalloc (size); + runtime->dma_area =vmalloc_user (size);if (runtime->dma_area ==NULL )return -ENOMEM ; runtime->dma_bytes = size;
sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c +1 -1
@@ -51,7 +51,7 @@ static int snd_pcm_alloc_vmalloc_buffer(return 0 ;/* already enough large */ vfree (runtime->dma_area); } - runtime->dma_area =vmalloc_32 (size); + runtime->dma_area =vmalloc_32_user (size);if (! runtime->dma_area)return -ENOMEM ; runtime->dma_bytes = size;
sound/usb/usbaudio.c +1 -1
@@ -752,7 +752,7 @@ static int snd_pcm_alloc_vmalloc_buffer(return 0 ;/* already large enough */ vfree (runtime->dma_area); } - runtime->dma_area =vmalloc (size); + runtime->dma_area =vmalloc_user (size);if (!runtime->dma_area)return -ENOMEM ; runtime->dma_bytes = size;
PATCH 14/39 USB: emi62: fix crash when trying to load EMI 6|2 firmware
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Clemens Ladisch <[email protected]>
commit ac06c06770bb8761b1f1f9bdf2f5420fa6d3e9fa upstream.
While converting emi62 to use request_firmware(), the driver was also changed to use the ihex helper functions. However, this broke the loading of the FPGA firmware because the code tries to access the addr field of the EOF record which works with a plain array that has an empty last record but not with the ihex helper functions where the end of the data is signaled with a NULL record pointer, resulting in:
BUG: unable to handle kernel NULL pointer dereference at (null) IP: [<f80d248c>] emi62_load_firmware+0x33c/0x740 [emi62]
This can be fixed by changing the loop condition to test the return value of ihex_next_binrec() directly (like in emi26.c).
--- drivers/usb/misc/emi62.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/misc/emi62.c +1 -1
@@ -167,7 +167,7 @@ static int emi62_load_firmware (struct uerr ("%s - error loading firmware: error = %d" , __func__, err); goto wraperr; } - }while (i >0 ); + }while (rec);/* Assert reset (stop the CPU in the EMI) */ err =emi62_set_reset (dev,1 );
PATCH 15/39 USB: Fix a bug on appledisplay.c regarding signedness
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: pancho horrillo <[email protected]>
commit 37e9066b2f85480d99d3795373f5ef0b00ac1189 upstream.
brightness status is reported by the Apple Cinema Displays as an 'unsigned char' (u8) value, but the code used 'char' instead.
Note that he driver was developed on the PowerPC architecture, where the two types are synonymous, which is not always the case.
Fixed that. Otherwise the driver will interpret brightness levels > 127 as negative, and fail to load.
--- drivers/usb/misc/appledisplay.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/usb/misc/appledisplay.c +2 -2
@@ -72,8 +72,8 @@ struct appledisplay {struct usb_device *udev;/* usb device */ struct urb *urb;/* usb request block */ struct backlight_device *bd;/* backlight device */ -char *urbdata;/* interrupt URB data buffer */ -char *msgdata;/* control message data buffer */ +u8 *urbdata;/* interrupt URB data buffer */ +u8 *msgdata;/* control message data buffer */ struct delayed_work work;int button_pressed;
PATCH 16/39 USB: musb: gadget_ep0: avoid SetupEnd interrupt
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Sergei Shtylyov <[email protected]>
commit 17be5c5f5ef99c94374e07f71effa78e93a20eda upstream.
Gadget stalling a zero-length SETUP request results in this error message:
SetupEnd came in a wrong ep0stage idle
In order to avoid it, always set the CSR0.DataEnd bit after detecting a zero- length request. Add the missing '\n' to the error message itself as well...
--- drivers/usb/musb/musb_gadget_ep0.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
drivers/usb/musb/musb_gadget_ep0.c +10 -4
@@ -646,7 +646,7 @@ irqreturn_t musb_g_ep0_irq(struct musb * musb->ep0_state =MUSB_EP0_STAGE_STATUSIN ;break ;default : -ERR ("SetupEnd came in a wrong ep0stage %s" , +ERR ("SetupEnd came in a wrong ep0stage %s\n" ,decode_ep0stage (musb->ep0_state)); } csr =musb_readw (regs,MUSB_CSR0 );
@@ -769,12 +769,18 @@ setup: handled =service_zero_data_request ( musb, &setup); +/* +* We're expecting no data in any case, so +* always set the DATAEND bit -- doing this +* here helps avoid SetupEnd interrupt coming +* in the idle stage when we're stalling... +*/ + musb->ackpend |=MUSB_CSR0_P_DATAEND ; +/* status stage might be immediate */ -if (handled >0 ) { - musb->ackpend |=MUSB_CSR0_P_DATAEND ; +if (handled >0 ) musb->ep0_state =MUSB_EP0_STAGE_STATUSIN ; - }break ;/* sequence #1 (IN to host), includes GET_STATUS
PATCH 17/39 USB: option: support hi speed for modem Haier CE100
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Donny Kurnia <[email protected]>
commit c983202bd03eb82394ef1dce5906702fcbc7bb80 upstream.
I made this patch for usbserial driver to add the support for EVDO modem Haier CE100. The bugs report for this is here:
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/490068
This patch based on these post:
http://blankblondtank.wordpress.com/2009/09/04/mengoptimalkan-koneksi-modem-haier-ce-100-cdma-di-linux/
http://tantos.web.id/blogs/how-to-internet-connection-using-cdma-evdo-modem-and-karmic-koala-ubuntu-9-10
I hope this patch can help other that have the Haier C100 modem, mostly in my country, Indonesia.
--- drivers/usb/serial/option.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/usb/serial/option.c +5 -0
@@ -337,6 +337,10 @@ static int option_resume(struct usb_ser#define AIRPLUS_VENDOR_ID 0x1011#define AIRPLUS_PRODUCT_MCD650 0x3198 +/* Haier products */ +#define HAIER_VENDOR_ID 0x201e +#define HAIER_PRODUCT_CE100 0x2009 +static struct usb_device_id option_ids[] = { {USB_DEVICE (OPTION_VENDOR_ID ,OPTION_PRODUCT_COLT ) }, {USB_DEVICE (OPTION_VENDOR_ID ,OPTION_PRODUCT_RICOLA ) },
@@ -637,6 +641,7 @@ static struct usb_device_id option_ids[] { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S) }, { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, { USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) }, + { USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) }, { } /* Terminating entry */ };MODULE_DEVICE_TABLE (usb, option_ids);
PATCH 18/39 x86, cpuid: Add "volatile" to asm in native_cpuid()
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Suresh Siddha <[email protected]>
commit 45a94d7cd45ed991914011919e7d40eb6d2546d1 upstream.
xsave_cntxt_init() does something like:
cpuid(0xd, ..); // find out what features FP/SSE/.. etc are supported xsetbv(); // enable the features known to OS cpuid(0xd, ..); // find out the size of the context for features enabled
Depending on what features get enabled in xsetbv(), value of the cpuid.eax=0xd.ecx=0.ebx changes correspondingly (representing the size of the context that is enabled).
As we don't have volatile keyword for native_cpuid(), gcc 4.1.2 optimizes away the second cpuid and the kernel continues to use the cpuid information obtained before xsetbv(), ultimately leading to kernel crash on processors supporting more state than the legacy FP/SSE.
Add "volatile" for native_cpuid().
LKML-Reference: <[email protected]>
--- arch/x86/include/asm/processor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/include/asm/processor.h +1 -1
@@ -179,7 +179,7 @@ static inline void native_cpuid(unsigned unsigned int *ecx, unsigned int *edx) { /* ecx is often an input as well as an output. */ - asm("cpuid" + asm volatile("cpuid" : "=a" (*eax), "=b" (*ebx), "=c" (*ecx),
PATCH 19/39 e100: Use pci pool to work around GFP_ATOMIC order 5 memory allocation failure
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Roger Oksanen <[email protected]>
commit 98468efddb101f8a29af974101c17ba513b07be1 upstream.
pci_alloc_consistent uses GFP_ATOMIC allocation that may fail on some systems with limited memory (Bug #14265). pci_pool_alloc allows waiting with GFP_KERNEL.
--- drivers/net/e100.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)
drivers/net/e100.c +11 -6
@@ -156,6 +156,7 @@#include <linux/init.h> #include <linux/pci.h> #include <linux/dma-mapping.h> +#include <linux/dmapool.h> #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/mii.h>
@@ -601,6 +602,7 @@ struct nic {struct mem *mem;dma_addr_t dma_addr; +struct pci_pool *cbs_pool;dma_addr_t cbs_dma_addr;u8 adaptive_ifs;u8 tx_threshold;
@@ -1779,9 +1781,7 @@ static void e100_clean_cbs(struct nic *n nic->cb_to_clean = nic->cb_to_clean->next; nic->cbs_avail++; } -pci_free_consistent (nic->pdev, -sizeof (struct cb ) * nic->params.cbs.count, - nic->cbs, nic->cbs_dma_addr); +pci_pool_free (nic->cbs_pool, nic->cbs, nic->cbs_dma_addr); nic->cbs =NULL ; nic->cbs_avail =0 ; }
@@ -1799,8 +1799,8 @@ static int e100_alloc_cbs(struct nic *ni nic->cb_to_use = nic->cb_to_send = nic->cb_to_clean =NULL ; nic->cbs_avail =0 ; - nic->cbs =pci_alloc_consistent (nic->pdev, -sizeof (struct cb ) * count, &nic->cbs_dma_addr); + nic->cbs =pci_pool_alloc (nic->cbs_pool,GFP_KERNEL , + &nic->cbs_dma_addr);if (!nic->cbs)return -ENOMEM ;
@@ -2827,7 +2827,11 @@ static int __devinit e100_probe(struct pDPRINTK (PROBE ,ERR ,"Cannot register net device, aborting.\n" ); goto err_out_free; } - + nic->cbs_pool =pci_pool_create (netdev->name, + nic->pdev, + nic->params.cbs.count *sizeof (struct cb ), +sizeof (u32), +0 );DPRINTK (PROBE ,INFO ,"addr 0x%llx, irq %d, MAC addr %pM\n" , (unsigned long long )pci_resource_start (pdev, use_io ?1 :0 ), pdev->irq, netdev->dev_addr);
@@ -2857,6 +2861,7 @@ static void __devexit e100_remove(structunregister_netdev (netdev);e100_free (nic);pci_iounmap (pdev, nic->csr); +pci_pool_destroy (nic->cbs_pool);free_netdev (netdev);pci_release_regions (pdev);pci_disable_device (pdev);
Re: [Stable-review] [19/39] e100: Use pci pool to work around GFP_ATOMIC order 5 memory allocation failure
Quoted 8 lines · On Tue, 05 Jan 2010 12:02:15 -0800 Greg KH <[email protected]> wrote:
2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Roger Oksanen <[email protected]>
commit
98468efddb101f8a29af974101c17ba513b07be1upstream.
Quoted 8 lines
pci_alloc_consistentusesGFP_ATOMICallocation that may fail on some systems with limited memory (Bug #14265).pci_pool_allocallows waiting withGFP_KERNEL.Tested-by Karol Lewandowski <[email protected]>Signed-off-by Roger Oksanen <[email protected]>Signed-off-by David S. Miller <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>
These two e100 patches in 2.6.31.10 (and 2.6.32) caused kernel panic on one customer system. I recommend they be reverted in next --stable update.
The user system configuration and backtrace were.
---
# lspci -v
00:00.0 Host bridge: VIA Technologies, Inc. VT8366/A/7 [Apollo KT266/A/333]
Subsystem: ASUSTeK Computer Inc. A7V266-E Mainboard
Flags: bus master, medium devsel, latency 0
Memory at fc000000 (32-bit, prefetchable) [size=32M]
Capabilities: [a0] AGP version 2.0
Capabilities: [c0] Power Management version 2
Kernel driver in use: agpgart-via
Kernel modules: via-agp00:01.0 PCI bridge: VIA Technologies, Inc. VT8366/A/7 [Apollo KT266/A/333 AGP] (prog-if 00 [Normal decode])
Flags: bus master, 66MHz, medium devsel, latency 0
Bus: primary=00, secondary=01, subordinate=01, sec-latency=0
Capabilities: [80] Power Management version 2
Kernel modules: shpchp
00:05.0 Multimedia audio controller: C-Media Electronics Inc CM8738 (rev 10)
Subsystem: ASUSTeK Computer Inc. CMI8738 6ch-MX
Flags: bus master, stepping, medium devsel, latency 32, IRQ 11 I/O ports at d800 [size=256]
Capabilities: [c0] Power Management version 2
00:06.0 Mass storage controller: Promise Technology, Inc. PDC20265 (FastTrak100 Lite/Ultra100) (rev 02)
Subsystem: Promise Technology, Inc. Ultra100
Flags: bus master, medium devsel, latency 32, IRQ 12
I/O ports at d400 [size=8]
I/O ports at d000 [size=4]
I/O ports at b800 [size=8]
I/O ports at b400 [size=4]
I/O ports at b000 [size=64]
Memory at fb000000 (32-bit, non-prefetchable) [size=128K]
[virtual] Expansion ROM at 80020000 [disabled] [size=64K]
Capabilities: [58] Power Management version 1
Kernel driver in use: pata_pdc202xx_old
Kernel modules: pata_pdc202xx_old00:0c.0 VGA compatible controller: S3 Inc. ViRGE/DX or /GX (rev 01) (prog-if 00 [VGA controller])
Subsystem: S3 Inc. ViRGE/DX
Flags: bus master, medium devsel, latency 32, IRQ 12
Memory at f4000000 (32-bit, non-prefetchable) [size=64M]
Expansion ROM at 80030000 [disabled] [size=64K]
Kernel modules: s3fb
00:0e.0 Ethernet controller: Intel Corporation 82557/8/9/0/1 Ethernet Pro 100 (rev 0c)
Subsystem: Intel Corporation EtherExpress PRO/100 S Desktop Adapter
Flags: bus master, medium devsel, latency 32, IRQ 11
Memory at f3800000 (32-bit, non-prefetchable) [size=4K]
I/O ports at a800 [size=64]
Memory at f3000000 (32-bit, non-prefetchable) [size=128K] [virtual] Expansion ROM at 80040000 [disabled] [size=64K]
Capabilities: [dc] Power Management version 2
Kernel driver in use: e100
Kernel modules: e100
00:0f.0 Ethernet controller: Intel Corporation 82541PI Gigabit Ethernet Controller (rev 05)
Subsystem: Intel Corporation PRO/1000 GT Desktop Adapter
Flags: bus master, 66MHz, medium devsel, latency 32, IRQ 10
Memory at f2800000 (32-bit, non-prefetchable) [size=128K]
Memory at f2000000 (32-bit, non-prefetchable) [size=128K]
I/O ports at a400 [size=64]
[virtual] Expansion ROM at 80000000 [disabled] [size=128K]
Capabilities: [dc] Power Management version 2
Capabilities: [e4] PCI-X non-bridge device
Kernel driver in use: e1000
Kernel modules: e1000
00:11.0 ISA bridge: VIA Technologies, Inc. VT8233 PCI to ISA Bridge
Subsystem: ASUSTeK Computer Inc. VT8233A
Flags: bus master, stepping, medium devsel, latency 0
Capabilities: [c0] Power Management version 2 Kernel modules: i2c-viapro
00:11.1 IDE interface: VIA Technologies, Inc. VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE (rev 06) (prog-if 8a [Master SecP PriP])
Flags: bus master, stepping, medium devsel, latency 32, IRQ 11
[virtual] Memory at 000001f0 (32-bit, non-prefetchable) [size=8]
[virtual] Memory at 000003f0 (type 3, non-prefetchable) [size=1]
[virtual] Memory at 00000170 (32-bit, non-prefetchable) [size=8]
[virtual] Memory at 00000370 (type 3, non-prefetchable) [size=1]
I/O ports at a000 [size=16]
Capabilities: [c0] Power Management version 2
Kernel driver in use: pata_via
Kernel modules: pata_via00:11.2 USB Controller: VIA Technologies, Inc. VT82xxxxx UHCI USB 1.1 Controller (rev 1b) (prog-if 00 [UHCI])
Subsystem: First International Computer, Inc. VA-502 Mainboard
Flags: bus master, medium devsel, latency 32, IRQ 12
I/O ports at 9800 [size=32]
Capabilities: [80] Power Management version 2
Kernel driver in use: uhci_hcd
Kernel modules: uhci-hcd
00:11.3 USB Controller: VIA Technologies, Inc. VT82xxxxx UHCI USB 1.1 Controller (rev 1b) (prog-if 00 [UHCI])
Subsystem: First International Computer, Inc. VA-502 Mainboard
Flags: bus master, medium devsel, latency 32, IRQ 12
I/O ports at 9400 [size=32]
Capabilities: [80] Power Management version 2
Kernel driver in use: uhci_hcd
Kernel modules: uhci-hcd
00:11.4 USB Controller: VIA Technologies, Inc. VT82xxxxx UHCI USB 1.1 Controller (rev 1b) (prog-if 00 [UHCI])
Subsystem: First International Computer, Inc. VA-502 Mainboard
Flags: bus master, medium devsel, latency 32, IRQ 12
I/O ports at 9000 [size=32]
Capabilities: [80] Power Management version 2
Kernel driver in use: uhci_hcd
Kernel modules: uhci-hcd
Code:
[ 849.707104] BUG: unable to handle kernel NULL pointer dereference at 00000002 [ 849.711050] IP: [<f7ca63e0>] e100_exec_cb+0x6b/0xd8 [e100] [ 849.711050] *pde = 00000000 [ 849.711050] Thread overran stack, or stack corrupted [ 849.711050] Oops: 0002 [#1] SMP [ 849.711050] last sysfs file: /sys/class/i2c-adapter/i2c-0/name [ 849.711050] Modules linked in: ip_gre xt_comment unionfs iptable_nat iptable_filter ip6table_filter ip6table_raw ip6_tables xt_NOTRACK iptable_raw ip_tables x_tables nf_nat_pptp nf_conntrack_pptp nf_conntrack_proto_gre nf_nat_h323 nf_conntrack_h323 nf_nat_sip nf_conntrack_sip nf_nat_proto_gre nf_nat_tftp nf_nat_ftp nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_conntrack_tftp nf_conntrack_ftp nf_conntrack ipv6 evdev serio_raw parport_pc pcspkr parport processor button i2c_viapro shpchp i2c_core pci_hotplug via_agp agpgart ext3 jbd mbcache raid6_pq async_xor async_memcpy async_tx xor md_mod sg usb_storage sr_mod cdrom sd_mod crc_t10dif pata_acpi ata_generic pata_pdc202xx_old pata_via uhci_hcd libata usbcore nls_base e1000 e100 mii scsi_mod thermal fan thermal_sys [last unloaded: raid10] [ 849.711050] [ 849.711050] Pid: 0, comm: swapper Tainted: G W (2.6.31-1-586-vyatta #1) System Name [ 849.711050] EIP: 0060:[<f7ca63e0>] EFLAGS: 00010006 CPU: 0 [ 849.711050] EIP is at e100_exec_cb+0x6b/0xd8 [e100] [ 849.711050] EAX: 00000000 EBX: f67dffe0 ECX: 000004ce EDX: 36697510 [ 849.711050] ESI: f6d8e340 EDI: 00000000 EBP: f67310c0 ESP: c12d1ca0 [ 849.711050] DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068 [ 849.711050] Process swapper (pid: 0, ti=c12d0000 task=c12febc0 task.ti=c12d0000) [ 849.711050] Stack: [ 849.711050] f7ca5190 f6d8e380 00000286 f6d8e000 f6d8e340 f67310c0 f6d8e000 f7ca68a5 [ 849.711050] <0> 00000000 f67310c0 c132d150 c11a3bb8 f64b9b80 f7ca83b8 00000004 00000000 [ 849.711050] <0> f64b9b80 f66b4100 f67310c0 c11b14a3 000218d2 f66b415c f6d8e000 f64b9b80 [ 849.711050] Call Trace: [ 849.711050] [<f7ca5190>] ? e100_xmit_prepare+0x0/0x97 [e100] [ 849.711050] [<f7ca68a5>] ? e100_xmit_frame+0x5b/0xd9 [e100] [ 849.711050] [<c11a3bb8>] ? dev_hard_start_xmit+0x205/0x298 [ 849.711050] [<c11b14a3>] ? __qdisc_run+0xbd/0x196 [ 849.711050] [<c11a3f6d>] ? dev_queue_xmit+0x243/0x336 [ 849.711050] [<c11c2098>] ? ip_finish_output2+0x189/0x1c4 [ 849.711050] [<c11c15d8>] ? ip_local_out+0x15/0x17 [ 849.711050] [<c11c1d8f>] ? ip_queue_xmit+0x2f4/0x338 [ 849.711050] [<c101c15f>] ? activate_task+0x1c/0x21 [ 849.711050] [<c1026086>] ? try_to_wake_up+0x193/0x19d [ 849.711050] [<c10a4a2e>] ? pollwake+0x5d/0x67 [ 849.711050] [<c11d3c46>] ? tcp_v4_send_check+0x7a/0xb0 [ 849.711050] [<c11d0833>] ? tcp_transmit_skb+0x5c9/0x602 [ 849.711050] [<c11d09d8>] ? tcp_send_ack+0xcf/0xd3 [ 849.711050] [<c11cef3d>] ? tcp_rcv_established+0x383/0x4cd [ 849.711050] [<c11d50a2>] ? tcp_v4_do_rcv+0x151/0x2a1 [ 849.711050] [<c11d5592>] ? tcp_v4_rcv+0x3a0/0x594 [ 849.711050] [<c11be22e>] ? ip_local_deliver_finish+0xca/0x14e [ 849.711050] [<c11bdeb5>] ? ip_rcv_finish+0x295/0x2a9 [ 849.711050] [<c11a3168>] ? netif_receive_skb+0x3cb/0x3e6 [ 849.711050] [<f7ca7afb>] ? e100_poll+0x184/0x29d [e100] [ 849.711050] [<c11a36b9>] ? net_rx_action+0x91/0x173 [ 849.711050] [<c102e431>] ? __do_softirq+0xa5/0x147 [ 849.711050] [<c102e4f6>] ? do_softirq+0x23/0x27 [ 849.711050] [<c102e5d3>] ? irq_exit+0x26/0x53 [ 849.711050] [<c10043fd>] ? do_IRQ+0x78/0x89 [ 849.711050] [<c1002fe9>] ? common_interrupt+0x29/0x30 [ 849.711050] [<c10085ae>] ? default_idle+0x3e/0x5c [ 849.711050] [<c1001c5c>] ? cpu_idle+0x41/0x5d [ 849.711050] [<c132e744>] ? start_kernel+0x29c/0x29f [ 849.711050] Code: 89 86 8c 00 00 00 89 f0 89 ab 2c 02 00 00 83 7e 50 01 19 ff 83 e7 e4 ff 14 24 66 81 4b 02 00 40 0f ae f8 8b c0 8b 83 24 02 00 00 <66> 81 60 02 ff bf eb 40 8b 88 28 02 00 00 89 f0 0f b6 56 4c e8 [ 849.711050] EIP: [<f7ca63e0>] e100_exec_cb+0x6b/0xd8 [e100] SS:ESP 0068:c12d1ca0 [ 849.711050] CR2: 0000000000000002 [ 849.711050] ---[ end trace 4eaa2a86a8e2da24 ]--- [ 849.711050] Kernel panic - not syncing: Fatal exception in interrupt [ 849.711050] Pid: 0, comm: swapper Tainted: G D W 2.6.31-1-586-vyatta #1 [ 849.711050] Call Trace: [ 849.711050] [<c120bee2>] ? panic+0x38/0xd1 [ 849.711050] [<c100581c>] ? oops_end+0x6c/0x76 [ 849.711050] [<c1017f6a>] ? no_context+0x105/0x10e [ 849.711050] [<c101809b>] ? __bad_area_nosemaphore+0x128/0x133 [ 849.711050] [<c101c15f>] ? activate_task+0x1c/0x21 [ 849.711050] [<f7f3f5de>] ? ipt_do_table+0x4b2/0x4f0 [ip_tables] [ 849.711050] [<f7ca5e09>] ? e100_exec_cmd+0x7f/0x88 [e100] [ 849.711050] [<f7ca6443>] ? e100_exec_cb+0xce/0xd8 [e100] [ 849.711050] [<c10181ce>] ? do_page_fault+0x0/0x270 [ 849.711050] [<c10180b0>] ? bad_area_nosemaphore+0xa/0xc [ 849.711050] [<c120dac6>] ? error_code+0x66/0x70 [ 849.711050] [<c10181ce>] ? do_page_fault+0x0/0x270 [ 849.711050] [<f7ca63e0>] ? e100_exec_cb+0x6b/0xd8 [e100] [ 849.711050] [<f7ca5190>] ? e100_xmit_prepare+0x0/0x97 [e100] [ 849.711050] [<f7ca68a5>] ? e100_xmit_frame+0x5b/0xd9 [e100] [ 849.711050] [<c11a3bb8>] ? dev_hard_start_xmit+0x205/0x298 [ 849.711050] [<c11b14a3>] ? __qdisc_run+0xbd/0x196 [ 849.711050] [<c11a3f6d>] ? dev_queue_xmit+0x243/0x336 [ 849.711050] [<c11c2098>] ? ip_finish_output2+0x189/0x1c4 [ 849.711050] [<c11c15d8>] ? ip_local_out+0x15/0x17 [ 849.711050] [<c11c1d8f>] ? ip_queue_xmit+0x2f4/0x338 [ 849.711050] [<c101c15f>] ? activate_task+0x1c/0x21 [ 849.711050] [<c1026086>] ? try_to_wake_up+0x193/0x19d [ 849.711050] [<c10a4a2e>] ? pollwake+0x5d/0x67 [ 849.711050] [<c11d3c46>] ? tcp_v4_send_check+0x7a/0xb0 [ 849.711050] [<c11d0833>] ? tcp_transmit_skb+0x5c9/0x602 [ 849.711050] [<c11d09d8>] ? tcp_send_ack+0xcf/0xd3 [ 849.711050] [<c11cef3d>] ? tcp_rcv_established+0x383/0x4cd [ 849.711050] [<c11d50a2>] ? tcp_v4_do_rcv+0x151/0x2a1 [ 849.711050] [<c11d5592>] ? tcp_v4_rcv+0x3a0/0x594 [ 849.711050] [<c11be22e>] ? ip_local_deliver_finish+0xca/0x14e [ 849.711050] [<c11bdeb5>] ? ip_rcv_finish+0x295/0x2a9 [ 849.711050] [<c11a3168>] ? netif_receive_skb+0x3cb/0x3e6 [ 849.711050] [<f7ca7afb>] ? e100_poll+0x184/0x29d [e100] [ 849.711050] [<c11a36b9>] ? net_rx_action+0x91/0x173 [ 849.711050] [<c102e431>] ? __do_softirq+0xa5/0x147 [ 849.711050] [<c102e4f6>] ? do_softirq+0x23/0x27 [ 849.711050] [<c102e5d3>] ? irq_exit+0x26/0x53 [ 849.711050] [<c10043fd>] ? do_IRQ+0x78/0x89 [ 849.711050] [<c1002fe9>] ? common_interrupt+0x29/0x30 [ 849.711050] [<c10085ae>] ? default_idle+0x3e/0x5c [ 849.711050] [<c1001c5c>] ? cpu_idle+0x41/0x5d [ 849.711050] [<c132e744>] ? start_kernel+0x29c/0x29f [ 849.711050] Rebooting in 60 seconds..
Re: [Stable-review] [19/39] e100: Use pci pool to work around GFP_ATOMIC order 5 memory allocation failure
From: Stephen Hemminger <[email protected]>
Date: Mon, 15 Mar 2010 14:29:53 -0700
Quoted 15 lines
Quoted 12 lines · On Tue, 05 Jan 2010 12:02:15 -0800 Greg KH <[email protected]> wrote:
2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Roger Oksanen <[email protected]>
commit
98468efddb101f8a29af974101c17ba513b07be1upstream.
pci_alloc_consistentusesGFP_ATOMICallocation that may fail on some systems with limited memory (Bug #14265).pci_pool_allocallows waiting withGFP_KERNEL.
Quoted 8 lines
Quoted 4 lines
Tested-by Karol Lewandowski <[email protected]>Signed-off-by Roger Oksanen <[email protected]>Signed-off-by David S. Miller <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>These two e100 patches in 2.6.31.10 (and 2.6.32) caused kernel panic on one customer system. I recommend they be reverted in next --stable update.
There was a subsequent fix that explicitly zeros out the memory. The problem was that whilst pci_alloc_consistent() zeros out the memory it returns, the pci pool stuff does not.
So please get that fix sent to -stable instead of the revert. For reference:
commit 70abc8cb90e679d8519721e2761d8366a18212a6
Author: Roger Oksanen <[email protected]> Date: Fri Dec 18 20:18:21 2009 -0800
e100: Fix broken cbs accounting due to missing memset.
Alan Stern noticed that e100 caused slab corruption.
commit 98468efddb101f8a29af974101c17ba513b07be1 changed
the allocation of cbs to use dma pools that don't return zeroed memory, especially the cb->status field used to track which cb to clean, causing (the visible) double freeing of skbs and a wrong free cbs count.
Now the cbs are explicitly zeroed at allocation time.
Re: [Stable-review] [19/39] e100: Use pci pool to work around GFP_ATOMIC order 5 memory allocation failure
Quoted 46 lines · On Mon, 15 Mar 2010 14:32:25 -0700 (PDT) David Miller <[email protected]>…
From: Stephen Hemminger <[email protected]>
Date: Mon, 15 Mar 2010 14:29:53 -0700Quoted 15 lines
Quoted 12 lines · On Tue, 05 Jan 2010 12:02:15 -0800 Greg KH <[email protected]> wrote:
2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Roger Oksanen <[email protected]>
commit
98468efddb101f8a29af974101c17ba513b07be1upstream.
pci_alloc_consistentusesGFP_ATOMICallocation that may fail on some systems with limited memory (Bug #14265).pci_pool_allocallows waiting withGFP_KERNEL.Quoted 8 lines
Quoted 4 lines
Tested-by Karol Lewandowski <[email protected]>Signed-off-by Roger Oksanen <[email protected]>Signed-off-by David S. Miller <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>These two e100 patches in 2.6.31.10 (and 2.6.32) caused kernel panic on one customer system. I recommend they be reverted in next --stable update.
There was a subsequent fix that explicitly zeros out the memory. The problem was that whilst
pci_alloc_consistent()zeros out the memory it returns, the pci pool stuff does not.So please get that fix sent to -stable instead of the revert. For reference:
commit
70abc8cb90e679d8519721e2761d8366a18212a6Author: Roger Oksanen <[email protected]> Date: Fri Dec 18 20:18:21 2009 -0800e100: Fix broken cbs accounting due to missing memset.
Alan Stern noticed that e100 caused slab corruption.
commit98468efddb101f8a29af974101c17ba513b07be1changed
the allocation of cbs to use dma pools that don't return zeroed memory, especially thecb->statusfield used to track which cb to clean, causing (the visible) double freeing of skbs and a wrong free cbs count.
Quoted 7 lines
Now the cbs are explicitly zeroed at allocation time.
Reported-by Alan Stern <[email protected]>Tested-by Alan Stern <[email protected]>Signed-off-by Roger Oksanen <[email protected]>Acked-by Jesse Brandeburg <[email protected]>Signed-off-by David S. Miller <[email protected]>
The kernel has both fixes in it. The customer reported that if both were reverted, the kernel panic went away.
commit 1bfc1db036675e61af0ea34d3ac18206de566b64
Author: Roger Oksanen <[email protected]> Date: Fri Dec 18 20:18:21 2009 -0800
e100: Fix broken cbs accounting due to missing memset.
commit 70abc8cb90e679d8519721e2761d8366a18212a6 upstream.
Alan Stern noticed that e100 caused slab corruption.
commit 98468efddb101f8a29af974101c17ba513b07be1 changed
the allocation of cbs to use dma pools that don't return zeroed memory, especially the cb->status field used to track which cb to clean, causing (the visible) double freeing of skbs and a wrong free cbs count.
Now the cbs are explicitly zeroed at allocation time.
commit 550b1d3896894543cc13dafe6910119024177482
Author: Roger Oksanen <[email protected]> Date: Sun Nov 29 17:17:29 2009 -0800
e100: Use pci pool to work around GFP_ATOMIC order 5 memory allocation failu
commit 98468efddb101f8a29af974101c17ba513b07be1 upstream.
pci_alloc_consistent uses GFP_ATOMIC allocation that may fail on some system with limited memory (Bug #14265). pci_pool_alloc allows waiting with GFP_KERNEL.
David Miller
maintainerRe: [Stable-review] [19/39] e100: Use pci pool to work around GFP_ATOMIC order 5 memory allocation failure
From: Stephen Hemminger <[email protected]>
Date: Mon, 15 Mar 2010 14:36:53 -0700
Quoted 2 lines
The kernel has both fixes in it. The customer reported that if both were reverted, the kernel panic went away.
Please recheck that as your backtrace matches exactly the crash signature fixed by the memset().
David Miller
maintainerRe: [Stable-review] [19/39] e100: Use pci pool to work around GFP_ATOMIC order 5 memory allocation failure
From: David Miller <[email protected]>
Date: Mon, 15 Mar 2010 14:39:06 -0700 (PDT)
Quoted 8 lines
From: Stephen Hemminger <[email protected]>
Date: Mon, 15 Mar 2010 14:36:53 -0700Quoted 2 lines
The kernel has both fixes in it. The customer reported that if both were reverted, the kernel panic went away.
Please recheck that as your backtrace matches exactly the crash signature fixed by the
memset().
As an update, after some auditing I found that ring parameter changes aren't handled correctly by the PCI pool changes and that might explain the crash.
I'll push the following fix around as soon as possible:
drivers/net/e100.c +1 -1
@@ -2858,7 +2858,7 @@ static int __devinit e100_probe(struct pci_dev *pdev, } nic->cbs_pool =pci_pool_create (netdev->name, nic->pdev, - nic->params.cbs.count *sizeof (struct cb ), + nic->params.cbs.max *sizeof (struct cb ),sizeof (u32),0 ); DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, MAC addr %pM\n",
Re: [Stable-review] [19/39] e100: Use pci pool to work around GFP_ATOMIC order 5 memory allocation failure
Quoted 23 lines · On Mon, 15 Mar 2010 15:20:37 -0700 (PDT) David Miller <[email protected]>…
From: David Miller <[email protected]>
Date: Mon, 15 Mar 2010 14:39:06 -0700 (PDT)Quoted 8 lines
From: Stephen Hemminger <[email protected]>
Date: Mon, 15 Mar 2010 14:36:53 -0700Quoted 2 lines
The kernel has both fixes in it. The customer reported that if both were reverted, the kernel panic went away.
Please recheck that as your backtrace matches exactly the crash signature fixed by the
memset().As an update, after some auditing I found that ring parameter changes aren't handled correctly by the PCI pool changes and that might explain the crash.
I'll push the following fix around as soon as possible:
drivers/net/e100.c +0
-0
drivers/net/e100.c static int __devinit e100_probe(struct pci_dev *pdev, · line 2864
Quoted 8 lines
drivers/net/e100.c +1
-1@@ -2858,7 +2858,7 @@ static int __devinit e100_probe(struct pci_dev *pdev, } nic->cbs_pool =pci_pool_create (netdev->name, nic->pdev, - nic->params.cbs.count *sizeof (struct cb ), + nic->params.cbs.max *sizeof (struct cb ),sizeof (u32),0 ); DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, MAC addr %pM\n",
I will cherry pick it back into our kernel for validation.
PATCH 20/39 e100: Fix broken cbs accounting due to missing memset.
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Roger Oksanen <[email protected]>
commit 70abc8cb90e679d8519721e2761d8366a18212a6 upstream.
Alan Stern noticed that e100 caused slab corruption.
commit 98468efddb101f8a29af974101c17ba513b07be1 changed
the allocation of cbs to use dma pools that don't return zeroed memory, especially the cb->status field used to track which cb to clean, causing (the visible) double freeing of skbs and a wrong free cbs count.
Now the cbs are explicitly zeroed at allocation time.
--- drivers/net/e100.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/e100.c +1 -1
@@ -1803,6 +1803,7 @@ static int e100_alloc_cbs(struct nic *ni &nic->cbs_dma_addr);if (!nic->cbs)return -ENOMEM ; +memset (nic->cbs,0 , count *sizeof (struct cb ));for (cb = nic->cbs, i =0 ; i < count; cb++, i++) { cb->next = (i +1 < count) ? cb +1 : nic->cbs;
@@ -1811,7 +1812,6 @@ static int e100_alloc_cbs(struct nic *ni cb->dma_addr = nic->cbs_dma_addr + i *sizeof (struct cb ); cb->link =cpu_to_le32 (nic->cbs_dma_addr + ((i+1 ) % count) *sizeof (struct cb )); - cb->skb =NULL ; } nic->cb_to_use = nic->cb_to_send = nic->cb_to_clean = nic->cbs;
PATCH 21/39 hostap: Revert a toxic part of the conversion to net_device_ops
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Martin Decky <[email protected]>
commit e484c16f6212f7f06407382efa4d3ad214b6c589 upstream.
As the hostap driver was converted to use net_device_ops, a mistake was made in hostap_main.c (commit 5ae4efbcd2611562a8b93596be034e63495706a5). Originally, the tx_queue_len was set to 0 for every other interface than HOSTAP_INTERFACE_MASTER, but the new fragment of code sets tx_queue_len to 0 only for HOSTAP_INTERFACE_MASTER. The opposite of the previous behavior makes the driver to drop all packets in AP mode.
Change the way 0 is assigned to tx_queue_len according to the original logic.
--- drivers/net/wireless/hostap/hostap_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/wireless/hostap/hostap_main.c +2 -1
@@ -875,15 +875,16 @@ void hostap_setup_dev(struct net_deviceswitch (type) {case HOSTAP_INTERFACE_AP : + dev->tx_queue_len =0 ;/* use main radio device queue */ dev->netdev_ops = &hostap_mgmt_netdev_ops; dev->type =ARPHRD_IEEE80211 ; dev->header_ops = &hostap_80211_ops;break ;case HOSTAP_INTERFACE_MASTER : - dev->tx_queue_len =0 ;/* use main radio device queue */ dev->netdev_ops = &hostap_master_ops;break ;default : + dev->tx_queue_len =0 ;/* use main radio device queue */ dev->netdev_ops = &hostap_netdev_ops; }
PATCH 22/39 hwmon: (fschmd) Fix check on unsigned in watchdog_write()
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Roel Kluin <[email protected]>
commit c7702c31340f84cfd5e5df22293578b7ae1e9370 upstream.
If unsigned the watchdog_trigger() return value will not be checked correctly.
--- drivers/hwmon/fschmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hwmon/fschmd.c +1 -1
@@ -819,7 +819,7 @@ static int watchdog_release(struct inodestatic ssize_t watchdog_write (struct file *filp,const char __user *buf,size_t count,loff_t *offset) { -size_t ret; +int ret;struct fschmd_data *data = filp->private_data;if (count) {
PATCH 23/39 hwmon: (sht15) Off-by-one error in array index + incorrect constants
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Jonathan Cameron <[email protected]>
commit 4235f684b66d6f00d2cd8849c884cf8f8b57ecad upstream.
Fix an off-by-one error in array index + incorrect constants.
--- drivers/hwmon/sht15.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/hwmon/sht15.c +3 -3
@@ -304,7 +304,7 @@ static inline int sht15_calc_temp(structint d1 =0 ;int i; -for (i =1 ; i <ARRAY_SIZE (temppoints) -1 ; i++) +for (i =1 ; i <ARRAY_SIZE (temppoints); i++)/* Find pointer to interpolate */ if (data->supply_uV > temppoints[i -1 ].vdd) { d1 = (data->supply_uV/1000 - temppoints[i -1 ].vdd)
@@ -331,12 +331,12 @@ static inline int sht15_calc_humid(strucconst int c1 =-4 ;const int c2 =40500 ;/* x 10 ^ -6 */ -const int c3 =2800 ;/* x10 ^ -9 */ +const int c3 =-2800 ;/* x10 ^ -9 */ RHlinear = c1*1000 + c2 * data->val_humid/1000 + (data->val_humid * data->val_humid * c3)/1000000 ; -return (temp -25000 ) * (10000 +800 * data->val_humid) +return (temp -25000 ) * (10000 +80 * data->val_humid) /1000000 + RHlinear; }
PATCH 24/39 i2c/tsl2550: Fix lux value in extended mode
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Michele Jr De Candia <[email protected]>
commit 5f5bfb09d81c9a1d26238ae6668e584c14ae3daf upstream.
According to the TAOS Application Note 'Controlling a Backlight with the TSL2550 Ambient Light Sensor' (page 14), the actual lux value in extended mode should be obtained multiplying the calculated lux value by 5.
--- drivers/i2c/chips/tsl2550.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/i2c/chips/tsl2550.c +3 -0
@@ -277,6 +277,7 @@ static DEVICE_ATTR(operating_mode, S_IWUstatic ssize_t __tsl2550_show_lux (struct i2c_client *client,char *buf) { +struct tsl2550_data *data =i2c_get_clientdata (client);u8 ch0, ch1;int ret;
@@ -296,6 +297,8 @@ static ssize_t __tsl2550_show_lux(struct ret =tsl2550_calculate_lux (ch0, ch1);if (ret <0 )return ret; +if (data->operating_mode ==1 ) + ret *=5 ;return sprintf (buf,"%d\n" , ret); }
PATCH 25/39 ipv6: reassembly: use seperate reassembly queues for conntrack and local delivery
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Patrick McHardy <[email protected]>
commit 0b5ccb2ee250136dd7385b1c7da28417d0d4d32d upstream.
Currently the same reassembly queue might be used for packets reassembled by conntrack in different positions in the stack (PREROUTING/LOCAL_OUT), as well as local delivery. This can cause "packet jumps" when the fragment completing a reassembled packet is queued from a different position in the stack than the previous ones.
Add a "user" identifier to the reassembly queue key to seperate the queues of each caller, similar to what we do for IPv4.
--- include/net/ipv6.h | 7 +++++++ include/net/netfilter/ipv6/nf_conntrack_ipv6.h | 2 +- net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 13 +++++++++++-- net/ipv6/netfilter/nf_conntrack_reasm.c | 7 ++++--- net/ipv6/reassembly.c | 5 ++++- 5 files changed, 27 insertions(+), 7 deletions(-)
include/net/ipv6.h +7 -0
@@ -354,8 +354,15 @@ static inline int ipv6_prefix_equal(consstruct inet_frag_queue ; +enum ip6_defrag_users { +IP6_DEFRAG_LOCAL_DELIVER , +IP6_DEFRAG_CONNTRACK_IN , +IP6_DEFRAG_CONNTRACK_OUT , +}; +struct ip6_create_arg {__be32 id; +u32 user;struct in6_addr *src;struct in6_addr *dst; };
include/net/netfilter/ipv6/nf_conntrack_ipv6.h +1 -1
@@ -9,7 +9,7 @@ extern struct nf_conntrack_l4proto nf_coextern int nf_ct_frag6_init (void );extern void nf_ct_frag6_cleanup (void ); -extern struct sk_buff *nf_ct_frag6_gather (struct sk_buff *skb); +extern struct sk_buff *nf_ct_frag6_gather (struct sk_buff *skb,u32 user); extern void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb, struct net_device *in, struct net_device *out,
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +11 -2
@@ -183,6 +183,16 @@ out:return nf_conntrack_confirm (skb); } +static enum ip6_defrag_users nf_ct6_defrag_user (unsigned int hooknum, +struct sk_buff *skb) +{ +if (hooknum ==NF_INET_PRE_ROUTING ) +return IP6_DEFRAG_CONNTRACK_IN ; +else +return IP6_DEFRAG_CONNTRACK_OUT ; + +} + static unsigned int ipv6_defrag(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in,
@@ -195,8 +205,7 @@ static unsigned int ipv6_defrag(unsignedif (skb->nfct)return NF_ACCEPT ; - reasm =nf_ct_frag6_gather (skb); - + reasm =nf_ct_frag6_gather (skb,nf_ct6_defrag_user (hooknum, skb));/* queued */ if (reasm ==NULL )return NF_STOLEN ;
net/ipv6/netfilter/nf_conntrack_reasm.c +4 -3
@@ -170,13 +170,14 @@ out:/* Creation primitives. */ static __inline__struct nf_ct_frag6_queue * -fq_find (__be32 id,struct in6_addr *src,struct in6_addr *dst) +fq_find (__be32 id,u32 user,struct in6_addr *src,struct in6_addr *dst) {struct inet_frag_queue *q;struct ip6_create_arg arg;unsigned int hash; arg.id = id; + arg.user = user; arg.src = src; arg.dst = dst;
@@ -561,7 +562,7 @@ find_prev_fhdr(struct sk_buff *skb, u8 *return 0 ; } -struct sk_buff *nf_ct_frag6_gather (struct sk_buff *skb) +struct sk_buff *nf_ct_frag6_gather (struct sk_buff *skb,u32 user) {struct sk_buff *clone;struct net_device *dev = skb->dev;
@@ -607,7 +608,7 @@ struct sk_buff *nf_ct_frag6_gather(strucif (atomic_read (&nf_init_frags.mem) > nf_init_frags.high_thresh)nf_ct_frag6_evictor (); - fq =fq_find (fhdr->identification, &hdr->saddr, &hdr->daddr); + fq =fq_find (fhdr->identification, user, &hdr->saddr, &hdr->daddr);if (fq ==NULL ) {pr_debug ("Can't find and can't create new queue\n" ); goto ret_orig;
net/ipv6/reassembly.c +4 -1
@@ -72,6 +72,7 @@ struct frag_queuestruct inet_frag_queue q;__be32 id;/* fragment id */ +u32 user;struct in6_addr saddr;struct in6_addr daddr;
@@ -141,7 +142,7 @@ int ip6_frag_match(struct inet_frag_queustruct ip6_create_arg *arg = a; fq = container_of(q, struct frag_queue, q); -return (fq->id == arg->id && +return (fq->id == arg->id && fq->user == arg->user &&ipv6_addr_equal (&fq->saddr, arg->src) &&ipv6_addr_equal (&fq->daddr, arg->dst)); }
@@ -163,6 +164,7 @@ void ip6_frag_init(struct inet_frag_queustruct ip6_create_arg *arg = a; fq->id = arg->id; + fq->user = arg->user;ipv6_addr_copy (&fq->saddr, arg->src);ipv6_addr_copy (&fq->daddr, arg->dst); }
@@ -244,6 +246,7 @@ fq_find(struct net *net, __be32 id, struunsigned int hash; arg.id = id; + arg.user =IP6_DEFRAG_LOCAL_DELIVER ; arg.src = src; arg.dst = dst;
PATCH 26/39 S390: dasd: support DIAG access for read-only devices
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Stefan Weinhuber <[email protected]>
commit 22825ab7693fd29769518a0d25ba43c01a50092a upstream.
When a DASD device is used with the DIAG discipline, the DIAG initialization will indicate success or error with a respective return code. So far we have interpreted a return code of 4 as error, but it actually means that the initialization was successful, but the device is read-only. To allow read-only devices to be used with DIAG we need to accept a return code of 4 as success.
Re-initialization of the DIAG access is also part of the DIAG error recovery. If we find that the access mode of a device has been changed from writable to read-only while the device was in use, we print an error message.
--- drivers/s390/block/dasd_diag.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-)
drivers/s390/block/dasd_diag.c +16 -3
@@ -145,6 +145,15 @@ dasd_diag_erp(struct dasd_device *devicemdsk_term_io (device); rc =mdsk_init_io (device, device->block->bp_block,0 ,NULL ); +if (rc ==4 ) { +if (!(device->features &DASD_FEATURE_READONLY )) { +dev_warn (&device->cdev->dev, +"The access mode of a DIAG device changed" +" to read-only" ); + device->features |=DASD_FEATURE_READONLY ; + } + rc =0 ; + }if (rc)dev_warn (&device->cdev->dev,"DIAG ERP failed with " "rc=%d\n" , rc);
@@ -433,16 +442,20 @@ dasd_diag_check_device(struct dasd_devicfor (sb =512 ; sb < bsize; sb = sb <<1 ) block->s2b_shift++; rc =mdsk_init_io (device, block->bp_block,0 ,NULL ); -if (rc) { +if (rc && (rc !=4 )) {dev_warn (&device->cdev->dev,"DIAG initialization " "failed with rc=%d\n" , rc); rc = -EIO ; }else { +if (rc ==4 ) + device->features |=DASD_FEATURE_READONLY ;dev_info (&device->cdev->dev, -"New DASD with %ld byte/block, total size %ld KB\n" , +"New DASD with %ld byte/block, total size %ld KB%s\n" , (unsigned long ) block->bp_block, (unsigned long ) (block->blocks << - block->s2b_shift) >>1 ); + block->s2b_shift) >>1 , + (rc ==4 ) ?", read-only device" :"" ); + rc =0 ; } out_label:free_page ((long ) label);
PATCH 27/39 udf: Try harder when looking for VAT inode
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Jan Kara <[email protected]>
commit e971b0b9e0dd50d9ceecb67a6a6ab80a80906033 upstream.
Some disks do not contain VAT inode in the last recorded block as required by the standard but a few blocks earlier (or the number of recorded blocks is wrong). So look for the VAT inode a bit before the end of the media.
--- fs/udf/super.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-)
fs/udf/super.c +24 -8
@@ -1078,21 +1078,39 @@ static int udf_fill_partdesc_info(structreturn 0 ; } -static int udf_load_vat (struct super_block *sb,int p_index,int type1_index) +static void udf_find_vat_block (struct super_block *sb,int p_index, +int type1_index,sector_t start_block) {struct udf_sb_info *sbi =UDF_SB (sb);struct udf_part_map *map = &sbi->s_partmaps[p_index]; +sector_t vat_block;struct kernel_lb_addr ino; + +/* +* VAT file entry is in the last recorded block. Some broken disks have +* it a few blocks before so try a bit harder... +*/ + ino.partitionReferenceNum = type1_index; +for (vat_block = start_block; + vat_block >= map->s_partition_root && + vat_block >= start_block -3 && + !sbi->s_vat_inode; vat_block--) { + ino.logicalBlockNum = vat_block - map->s_partition_root; + sbi->s_vat_inode =udf_iget (sb, &ino); + } +} + +static int udf_load_vat (struct super_block *sb,int p_index,int type1_index) +{ +struct udf_sb_info *sbi =UDF_SB (sb); +struct udf_part_map *map = &sbi->s_partmaps[p_index];struct buffer_head *bh =NULL ;struct udf_inode_info *vati;uint32_t pos;struct virtualAllocationTable20 *vat20;sector_t blocks = sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits; -/* VAT file entry is in the last recorded block */ - ino.partitionReferenceNum = type1_index; - ino.logicalBlockNum = sbi->s_last_block - map->s_partition_root; - sbi->s_vat_inode =udf_iget (sb, &ino); +udf_find_vat_block (sb, p_index, type1_index, sbi->s_last_block);if (!sbi->s_vat_inode && sbi->s_last_block != blocks -1 ) { printk(KERN_NOTICE "UDF-fs: Failed to read VAT inode from the"
@@ -1100,9 +1118,7 @@ static int udf_load_vat(struct super_blo"block of the device (%lu).\n" , (unsigned long )sbi->s_last_block, (unsigned long)blocks - 1); - ino.partitionReferenceNum = type1_index; - ino.logicalBlockNum = blocks -1 - map->s_partition_root; - sbi->s_vat_inode =udf_iget (sb, &ino); +udf_find_vat_block (sb, p_index, type1_index, blocks -1 ); }if (!sbi->s_vat_inode)return 1 ;
PATCH 28/39 V4L/DVB (13596): ov511.c typo: lock => unlock
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dan Carpenter <[email protected]>
commit 50e9d31183ed61c787b870cb3ee8f6c3db8c8a1e upstream.
This was found with a static checker and has not been tested, but it seems pretty clear that the mutex_lock() was supposed to be mutex_unlock()
--- drivers/media/video/ov511.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/video/ov511.c +1 -1
@@ -5878,7 +5878,7 @@ ov51x_probe(struct usb_interface *intf, goto error; } -mutex_lock (&ov->lock); +mutex_unlock (&ov->lock);return 0 ;
PATCH 29/39 x86/ptrace: make genregs[32]_get/set more robust
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Linus Torvalds <[email protected]>
commit 04a1e62c2cec820501f93526ad1e46073b802dc4 upstream.
The loop condition is fragile: we compare an unsigned value to zero, and then decrement it by something larger than one in the loop. All the callers should be passing in appropriately aligned buffer lengths, but it's better to just not rely on it, and have some appropriate defensive loop limits.
--- arch/x86/kernel/ptrace.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
arch/x86/kernel/ptrace.c +8 -8
@@ -417,14 +417,14 @@ static int genregs_get(struct task_struc {if (kbuf) {unsigned long *k = kbuf; -while (count >0 ) { +while (count >=sizeof (*k)) { *k++ =getreg (target, pos); count -=sizeof (*k); pos +=sizeof (*k); } }else {unsigned long __user *u = ubuf; -while (count >0 ) { +while (count >=sizeof (*u)) {if (__put_user (getreg (target, pos), u++))return -EFAULT ; count -=sizeof (*u);
@@ -443,14 +443,14 @@ static int genregs_set(struct task_strucint ret =0 ;if (kbuf) {const unsigned long *k = kbuf; -while (count >0 && !ret) { +while (count >=sizeof (*k) && !ret) { ret =putreg (target, pos, *k++); count -=sizeof (*k); pos +=sizeof (*k); } }else {const unsigned long __user *u = ubuf; -while (count >0 && !ret) { +while (count >=sizeof (*u) && !ret) {unsigned long word; ret =__get_user (word, u++);if (ret)
@@ -1223,14 +1223,14 @@ static int genregs32_get(struct task_str {if (kbuf) {compat_ulong_t *k = kbuf; -while (count >0 ) { +while (count >=sizeof (*k)) {getreg32 (target, pos, k++); count -=sizeof (*k); pos +=sizeof (*k); } }else {compat_ulong_t __user *u = ubuf; -while (count >0 ) { +while (count >=sizeof (*u)) {compat_ulong_t word;getreg32 (target, pos, &word);if (__put_user (word, u++))
@@ -1251,14 +1251,14 @@ static int genregs32_set(struct task_strint ret =0 ;if (kbuf) {const compat_ulong_t *k = kbuf; -while (count >0 && !ret) { +while (count >=sizeof (*k) && !ret) { ret =putreg32 (target, pos, *k++); count -=sizeof (*k); pos +=sizeof (*k); } }else {const compat_ulong_t __user *u = ubuf; -while (count >0 && !ret) { +while (count >=sizeof (*u) && !ret) {compat_ulong_t word; ret =__get_user (word, u++);if (ret)
PATCH 30/39 XFS bug in log recover with quota (bugzilla id 855)
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Jan Rekorajski <[email protected]>
commit 8ec6dba2581754e375be66f7bedd708d856d8b30 upstream.
Hi,
I was hit by a bug in linux 2.6.31 when XFS is not able to recover the log after a crash if fs was mounted with quotas. Gory details in XFS
bugzilla: http://oss.sgi.com/bugzilla/show_bug.cgi?id=855.
It looks like wrong struct is used in buffer length check, and the following patch should fix the problem.
xfs_dqblk_t has a size of 104+32 bytes, while xfs_disk_dquot_t is 104 bytes long, and this is exactly what I see in system logs - "XFS: dquot too small
(104) in xlog_recover_do_dquot_trans."
--- fs/xfs/xfs_log_recover.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/xfs/xfs_log_recover.c +2 -2
@@ -1980,7 +1980,7 @@ xlog_recover_do_reg_buffer( "XFS: NULL dquot in %s.", __func__); goto next; } -if (item->ri_buf[i].i_len <sizeof (xfs_dqblk_t)) { +if (item->ri_buf[i].i_len <sizeof (xfs_disk_dquot_t)) {cmn_err (CE_ALERT ,"XFS: dquot too small (%d) in %s." , item->ri_buf[i].i_len, __func__);
@@ -2635,7 +2635,7 @@ xlog_recover_do_dquot_trans( "XFS: NULL dquot in %s.", __func__);return XFS_ERROR (EIO ); } -if (item->ri_buf[1 ].i_len <sizeof (xfs_dqblk_t)) { +if (item->ri_buf[1 ].i_len <sizeof (xfs_disk_dquot_t)) {cmn_err (CE_ALERT ,"XFS: dquot too small (%d) in %s." , item->ri_buf[1 ].i_len, __func__);
PATCH 31/39 generic_permission: MAY_OPEN is not write access
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Serge E. Hallyn <[email protected]>
commit 7ea6600148c265b1fd53e521022b1d7aec81d974 upstream.
generic_permission was refusing CAP_DAC_READ_SEARCH-enabled processes from opening DAC-protected files read-only, because do_filp_open adds MAY_OPEN to the open mask.
Ignore MAY_OPEN. After this patch, CAP_DAC_READ_SEARCH is again sufficient to open(fname, O_RDONLY) on a file to which DAC otherwise refuses us read permission.
--- fs/namei.c | 1 + 1 file changed, 1 insertion(+)
fs/namei.c +1 -0
@@ -221,6 +221,7 @@ int generic_permission(struct inode *ino/* * Searching includes executable on directories, else just read. */ + mask &=MAY_READ |MAY_WRITE |MAY_EXEC ;if (mask ==MAY_READ || (S_ISDIR (inode->i_mode) && !(mask &MAY_WRITE )))if (capable (CAP_DAC_READ_SEARCH ))return 0 ;
PATCH 32/39 rt2x00: Disable powersaving for rt61pci and rt2800pci.
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Gertjan van Wingerde <[email protected]>
commit 93b6bd26b74efe46b4579592560f9f1cb7b61994 upstream.
We've had many reports of rt61pci failures with powersaving enabled. Therefore, as a stop-gap measure, disable powersaving of the rt61pci until we have found a proper solution.
Also disable powersaving on rt2800pci as it most probably will show the same problem.
--- drivers/net/wireless/rt2x00/rt61pci.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/net/wireless/rt2x00/rt61pci.c +5 -0
@@ -2546,6 +2546,11 @@ static int rt61pci_probe_hw_mode(structunsigned int i;/* +* Disable powersaving as default. +*/ + rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT ; + +/* * Initialize all hw fields. */ rt2x00dev->hw->flags =
Re: [32/39] rt2x00: Disable powersaving for rt61pci and rt2800pci.
Quoted 30 lines · Greg KH
2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Gertjan van Wingerde <[email protected]>
commit
93b6bd26b74efe46b4579592560f9f1cb7b61994upstream.We've had many reports of rt61pci failures with powersaving enabled. Therefore, as a stop-gap measure, disable powersaving of the rt61pci until we have found a proper solution.
Also disable powersaving on rt2800pci as it most probably will show the same problem.Signed-off-by Gertjan van Wingerde <[email protected]>Acked-by Ivo van Doorn <[email protected]>Signed-off-by John W. Linville <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- drivers/net/wireless/rt2x00/rt61pci.c | 5 +++++ 1 file changed, 5 insertions(+)drivers/net/wireless/rt2x00/rt61pci.c +0
-0@@ -2546,6 +2546,11 @@ static int rt61pci_probe_hw_mode(structunsigned int i;
drivers/net/wireless/rt2x00/rt61pci.c static int rt61pci_probe_hw_mode(struct · line 2556
Quoted 10 lines
drivers/net/wireless/rt2x00/rt61pci.c +5
-0/* +* Disable powersaving as default. +*/ + rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT ; + +/* * Initialize all hw fields. */ rt2x00dev->hw->flags =
Same as for .32-stable. An updated patch (as sent by John Linville) is needed to compile correctly.
---
Gertjan.
Re: [32/39] rt2x00: Disable powersaving for rt61pci and rt2800pci.
Quoted 29 lines · Gertjan van Wingerde
Quoted 28 lines · Greg KH
2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Gertjan van Wingerde <[email protected]>
commit
93b6bd26b74efe46b4579592560f9f1cb7b61994upstream.We've had many reports of rt61pci failures with powersaving enabled. Therefore, as a stop-gap measure, disable powersaving of the rt61pci until we have found a proper solution.
Also disable powersaving on rt2800pci as it most probably will show the same problem.Signed-off-by Gertjan van Wingerde <[email protected]>Acked-by Ivo van Doorn <[email protected]>Signed-off-by John W. Linville <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- drivers/net/wireless/rt2x00/rt61pci.c | 5 +++++ 1 file changed, 5 insertions(+)drivers/net/wireless/rt2x00/rt61pci.c +0
-0@@ -2546,6 +2546,11 @@ static int rt61pci_probe_hw_mode(structunsigned int i;
Quoted 15 lines
drivers/net/wireless/rt2x00/rt61pci.c static int rt61pci_probe_hw_mode(struct · line 2556
Quoted 12 lines
drivers/net/wireless/rt2x00/rt61pci.c +5
-0/* +* Disable powersaving as default. +*/ + rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT ; + +/* * Initialize all hw fields. */ rt2x00dev->hw->flags =Same as for .32-stable. An updated patch (as sent by John Linville) is needed to compile correctly.
Ick, sorry about that, I've fixed up the .31 patch, will go fix up the .32 patch now as well.
thanks,
greg k-h
PATCH 33/39 memcg: avoid oom-killing innocent task in case of use_hierarchy
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Daisuke Nishimura <[email protected]>
commit d31f56dbf8bafaacb0c617f9a6f137498d5c7aed upstream
task_in_mem_cgroup(), which is called by select_bad_process() to check whether a task can be a candidate for being oom-killed from memcg's limit, checks "curr->use_hierarchy"("curr" is the mem_cgroup the task belongs to).
But this check return true(it's false positive) when:
<some path>/00 use_hierarchy == 0 <- hitting limit <some path>/00/aa use_hierarchy == 1 <- "curr"
This leads to killing an innocent task in 00/aa. This patch is a fix for this bug. And this patch also fixes the arg for mem_cgroup_print_oom_info(). We should print information of mem_cgroup which the task being killed, not current, belongs to.
--- mm/memcontrol.c | 8 +++++++- mm/oom_kill.c | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-)
mm/memcontrol.c +7 -1
@@ -496,7 +496,13 @@ int task_in_mem_cgroup(struct task_structask_unlock (task);if (!curr)return 0 ; -if (curr->use_hierarchy) +/* +* We should check use_hierarchy of "mem" not "curr". Because checking +* use_hierarchy of "curr" here make this function true if hierarchy is +* enabled in "curr" and "curr" is a child of "mem" in *cgroup* +* hierarchy(even if use_hierarchy is disabled in "mem"). +*/ +if (mem->use_hierarchy) ret =css_is_ancestor (&curr->css, &mem->css);else ret = (curr == mem);
mm/oom_kill.c +1 -1
@@ -400,7 +400,7 @@ static int oom_kill_process(struct task_cpuset_print_task_mems_allowed (current);task_unlock (current);dump_stack (); -mem_cgroup_print_oom_info (mem, current); +mem_cgroup_print_oom_info (mem, p);show_mem ();if (sysctl_oom_dump_tasks)dump_tasks (mem);
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 34/39 Input: atkbd - add force relese key quirk for Samsung R59P/R60P/R61P
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Moiseev Vladimir <[email protected]>
This patch is not upstream. Since 2.6.32, there is an interface in /sys for handling the force_release events from userspace, so such quirk patches are no longer accepted upstream now. But this patch is valid for version 2.6.31 downwards.
OriginalAuthor:
Moiseev Vladimir <[email protected]>
Alexander Huhlaev <[email protected]>
--- drivers/input/keyboard/atkbd.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/input/keyboard/atkbd.c +9 -0
@@ -1608,6 +1608,15 @@ static struct dmi_system_id atkbd_dmi_qu .driver_data = atkbd_samsung_forced_release_keys, }, { + .ident = "Samsung R59P/R60P/R61P", + .matches = { +DMI_MATCH (DMI_SYS_VENDOR ,"SAMSUNG ELECTRONICS CO., LTD." ), + DMI_MATCH(DMI_PRODUCT_NAME, "R59P/R60P/R61P"), + }, + .callback = atkbd_setup_forced_release, + .driver_data = atkbd_samsung_forced_release_keys, + }, + { .ident ="Fujitsu Amilo PA 1510" , .matches = { DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
PATCH 35/39 Add unlocked version of inode_add_bytes() function
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dmitry Monakhov <[email protected]>
commit b462707e7ccad058ae151e5c5b06eb5cadcb737f upstream.
Quota code requires unlocked version of this function. Off course we can just copy-paste the code, but copy-pasting is always an evil.
--- fs/stat.c | 10 ++++++++-- include/linux/fs.h | 1 + 2 files changed, 9 insertions(+), 2 deletions(-)
fs/stat.c +8 -2
@@ -401,9 +401,9 @@ SYSCALL_DEFINE4(fstatat64, int, dfd, cha }#endif /* __ARCH_WANT_STAT64 */ -void inode_add_bytes (struct inode *inode,loff_t bytes) +/* Caller is here responsible for sufficient locking (ie. inode->i_lock) */ +void __inode_add_bytes (struct inode *inode,loff_t bytes) { -spin_lock (&inode->i_lock); inode->i_blocks += bytes >>9 ; bytes &=511 ; inode->i_bytes += bytes;
@@ -411,6 +411,12 @@ void inode_add_bytes(struct inode *inode inode->i_blocks++; inode->i_bytes -=512 ; } +} + +void inode_add_bytes (struct inode *inode,loff_t bytes) +{ +spin_lock (&inode->i_lock); +__inode_add_bytes (inode, bytes);spin_unlock (&inode->i_lock); }
include/linux/fs.h +1 -0
@@ -2296,6 +2296,7 @@ extern const struct inode_operations pagextern int generic_readlink (struct dentry *,char __user *,int );extern void generic_fillattr (struct inode *,struct kstat *);extern int vfs_getattr (struct vfsmount *,struct dentry *,struct kstat *); +void __inode_add_bytes (struct inode *inode,loff_t bytes);void inode_add_bytes (struct inode *inode,loff_t bytes);void inode_sub_bytes (struct inode *inode,loff_t bytes);loff_t inode_get_bytes (struct inode *inode);
PATCH 36/39 quota: decouple fs reserved space from quota reservation
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dmitry Monakhov <[email protected]>
commit fd8fbfc1709822bd94247c5b2ab15a5f5041e103 upstream.
Currently inode_reservation is managed by fs itself and this reservation is transfered on dquot_transfer(). This means what inode_reservation must always be in sync with dquot->dq_dqb.dqb_rsvspace. Otherwise dquot_transfer() will result in incorrect quota(WARN_ON in dquot_claim_reserved_space() will be triggered)
This is not easy because of complex locking order issues for example http://bugzilla.kernel.org/show_bug.cgi?id=14739
The patch introduce quota reservation field for each fs-inode (fs specific inode is used in order to prevent bloating generic vfs inode). This reservation is managed by quota code internally similar to i_blocks/i_bytes and may not be always in sync with internal fs reservation.
Also perform some code rearrangement:
- Unify dquot_reserve_space() and dquot_reserve_space()
- Unify dquot_release_reserved_space() and dquot_free_space()
- Also this patch add missing warning update to release_rsv() dquot_release_reserved_space() must call flush_warnings() as dquot_free_space() does.
--- fs/quota/dquot.c | 213 +++++++++++++++++++++++++++----------------------- include/linux/quota.h | 5 - 2 files changed, 122 insertions(+), 96 deletions(-)
fs/quota/dquot.c +119 -94
@@ -1388,6 +1388,67 @@ void vfs_dq_drop(struct inode *inode)EXPORT_SYMBOL (vfs_dq_drop);/* +* inode_reserved_space is managed internally by quota, and protected by +* i_lock similar to i_blocks+i_bytes. +*/ +static qsize_t *inode_reserved_space (struct inode * inode) +{ +/* Filesystem must explicitly define it's own method in order to use +* quota reservation interface */ +BUG_ON (!inode->i_sb->dq_op->get_reserved_space); +return inode->i_sb->dq_op->get_reserved_space (inode); +} + +static void inode_add_rsv_space (struct inode *inode,qsize_t number) +{ +spin_lock (&inode->i_lock); + *inode_reserved_space (inode) += number; +spin_unlock (&inode->i_lock); +} + + +static void inode_claim_rsv_space (struct inode *inode,qsize_t number) +{ +spin_lock (&inode->i_lock); + *inode_reserved_space (inode) -= number; +__inode_add_bytes (inode, number); +spin_unlock (&inode->i_lock); +} + +static void inode_sub_rsv_space (struct inode *inode,qsize_t number) +{ +spin_lock (&inode->i_lock); + *inode_reserved_space (inode) -= number; +spin_unlock (&inode->i_lock); +} + +static qsize_t inode_get_rsv_space (struct inode *inode) +{ +qsize_t ret; +spin_lock (&inode->i_lock); + ret = *inode_reserved_space (inode); +spin_unlock (&inode->i_lock); +return ret; +} + +static void inode_incr_space (struct inode *inode,qsize_t number, +int reserve) +{ +if (reserve) +inode_add_rsv_space (inode, number); +else +inode_add_bytes (inode, number); +} + +static void inode_decr_space (struct inode *inode,qsize_t number,int reserve) +{ +if (reserve) +inode_sub_rsv_space (inode, number); +else +inode_sub_bytes (inode, number); +} + +/* * Following four functions update i_blocks+i_bytes fields and * quota information (together with appropriate checks) * NOTE: We absolutely rely on the fact that caller dirties
@@ -1405,6 +1466,21 @@ int __dquot_alloc_space(struct inode *inint cnt, ret =QUOTA_OK ;char warntype[MAXQUOTAS ]; +/* +* First test before acquiring mutex - solves deadlocks when we +* re-enter the quota code and are already holding the mutex +*/ +if (IS_NOQUOTA (inode)) { +inode_incr_space (inode, number, reserve); + goto out; + } + +down_read (&sb_dqopt (inode->i_sb)->dqptr_sem); +if (IS_NOQUOTA (inode)) { +inode_incr_space (inode, number, reserve); + goto out_unlock; + } +for (cnt =0 ; cnt <MAXQUOTAS ; cnt++) warntype[cnt] =QUOTA_NL_NOWARN ;
@@ -1415,7 +1491,8 @@ int __dquot_alloc_space(struct inode *inif (check_bdq (inode->i_dquot[cnt], number, warn, warntype+cnt) ==NO_QUOTA ) { ret =NO_QUOTA ; - goto out_unlock; +spin_unlock (&dq_data_lock); + goto out_flush_warn; } }for (cnt =0 ; cnt <MAXQUOTAS ; cnt++) {
@@ -1426,64 +1503,32 @@ int __dquot_alloc_space(struct inode *inelse dquot_incr_space (inode->i_dquot[cnt], number); } -if (!reserve) -inode_add_bytes (inode, number); -out_unlock: +inode_incr_space (inode, number, reserve);spin_unlock (&dq_data_lock); -flush_warnings (inode->i_dquot, warntype); -return ret; -} - -int dquot_alloc_space (struct inode *inode,qsize_t number,int warn) -{ -int cnt, ret =QUOTA_OK ; - -/* -* First test before acquiring mutex - solves deadlocks when we -* re-enter the quota code and are already holding the mutex -*/ -if (IS_NOQUOTA (inode)) { -inode_add_bytes (inode, number); - goto out; - } - -down_read (&sb_dqopt (inode->i_sb)->dqptr_sem); -if (IS_NOQUOTA (inode)) { -inode_add_bytes (inode, number); - goto out_unlock; - } - - ret =__dquot_alloc_space (inode, number, warn,0 ); -if (ret ==NO_QUOTA ) - goto out_unlock; +if (reserve) + goto out_flush_warn;/* Dirtify all the dquots - this can block when journalling */ for (cnt =0 ; cnt <MAXQUOTAS ; cnt++)if (inode->i_dquot[cnt])mark_dquot_dirty (inode->i_dquot[cnt]); +out_flush_warn: +flush_warnings (inode->i_dquot, warntype); out_unlock:up_read (&sb_dqopt (inode->i_sb)->dqptr_sem); out:return ret; } + +int dquot_alloc_space (struct inode *inode,qsize_t number,int warn) +{ +return __dquot_alloc_space (inode, number, warn,0 ); +}EXPORT_SYMBOL (dquot_alloc_space);int dquot_reserve_space (struct inode *inode,qsize_t number,int warn) { -int ret =QUOTA_OK ; - -if (IS_NOQUOTA (inode)) - goto out; - -down_read (&sb_dqopt (inode->i_sb)->dqptr_sem); -if (IS_NOQUOTA (inode)) - goto out_unlock; - - ret =__dquot_alloc_space (inode, number, warn,1 ); -out_unlock: -up_read (&sb_dqopt (inode->i_sb)->dqptr_sem); -out: -return ret; +return __dquot_alloc_space (inode, number, warn,1 ); }EXPORT_SYMBOL (dquot_reserve_space);
@@ -1540,14 +1585,14 @@ int dquot_claim_space(struct inode *inodint ret =QUOTA_OK ;if (IS_NOQUOTA (inode)) { -inode_add_bytes (inode, number); +inode_claim_rsv_space (inode, number); goto out; }down_read (&sb_dqopt (inode->i_sb)->dqptr_sem);if (IS_NOQUOTA (inode)) {up_read (&sb_dqopt (inode->i_sb)->dqptr_sem); -inode_add_bytes (inode, number); +inode_claim_rsv_space (inode, number); goto out; }
@@ -1559,7 +1604,7 @@ int dquot_claim_space(struct inode *inod number); }/* Update inode bytes */ -inode_add_bytes (inode, number); +inode_claim_rsv_space (inode, number);spin_unlock (&dq_data_lock);/* Dirtify all the dquots - this can block when journalling */ for (cnt =0 ; cnt <MAXQUOTAS ; cnt++)
@@ -1572,38 +1617,9 @@ out:EXPORT_SYMBOL (dquot_claim_space);/* -* Release reserved quota space -*/ -void dquot_release_reserved_space (struct inode *inode,qsize_t number) -{ -int cnt; - -if (IS_NOQUOTA (inode)) - goto out; - -down_read (&sb_dqopt (inode->i_sb)->dqptr_sem); -if (IS_NOQUOTA (inode)) - goto out_unlock; - -spin_lock (&dq_data_lock); -/* Release reserved dquots */ -for (cnt =0 ; cnt <MAXQUOTAS ; cnt++) { -if (inode->i_dquot[cnt]) -dquot_free_reserved_space (inode->i_dquot[cnt], number); - } -spin_unlock (&dq_data_lock); - -out_unlock: -up_read (&sb_dqopt (inode->i_sb)->dqptr_sem); -out: -return ; -} -EXPORT_SYMBOL (dquot_release_reserved_space); - -/* * This operation can block, but only after everything is updated */ -int dquot_free_space (struct inode *inode,qsize_t number) +int __dquot_free_space (struct inode *inode,qsize_t number,int reserve) {unsigned int cnt;char warntype[MAXQUOTAS ];
@@ -1612,7 +1628,7 @@ int dquot_free_space(struct inode *inode* re-enter the quota code and are already holding the mutex */ if (IS_NOQUOTA (inode)) { out_sub: -inode_sub_bytes (inode, number); +inode_decr_space (inode, number, reserve);return QUOTA_OK ; }
@@ -1627,21 +1643,43 @@ out_sub:if (!inode->i_dquot[cnt])continue ; warntype[cnt] =info_bdq_free (inode->i_dquot[cnt], number); -dquot_decr_space (inode->i_dquot[cnt], number); +if (reserve) +dquot_free_reserved_space (inode->i_dquot[cnt], number); +else +dquot_decr_space (inode->i_dquot[cnt], number); } -inode_sub_bytes (inode, number); +inode_decr_space (inode, number, reserve);spin_unlock (&dq_data_lock); + +if (reserve) + goto out_unlock;/* Dirtify all the dquots - this can block when journalling */ for (cnt =0 ; cnt <MAXQUOTAS ; cnt++)if (inode->i_dquot[cnt])mark_dquot_dirty (inode->i_dquot[cnt]); +out_unlock:flush_warnings (inode->i_dquot, warntype);up_read (&sb_dqopt (inode->i_sb)->dqptr_sem);return QUOTA_OK ; } + +int dquot_free_space (struct inode *inode,qsize_t number) +{ +return __dquot_free_space (inode, number,0 ); +}EXPORT_SYMBOL (dquot_free_space);/* +* Release reserved quota space +*/ +void dquot_release_reserved_space (struct inode *inode,qsize_t number) +{ +__dquot_free_space (inode, number,1 ); + +} +EXPORT_SYMBOL (dquot_release_reserved_space); + +/* * This operation can block, but only after everything is updated */ int dquot_free_inode (const struct inode *inode,qsize_t number)
@@ -1679,19 +1717,6 @@ int dquot_free_inode(const struct inodeEXPORT_SYMBOL (dquot_free_inode);/* -* call back function, get reserved quota space from underlying fs -*/ -qsize_t dquot_get_reserved_space (struct inode *inode) -{ -qsize_t reserved_space =0 ; - -if (sb_any_quota_active (inode->i_sb) && - inode->i_sb->dq_op->get_reserved_space) - reserved_space = inode->i_sb->dq_op->get_reserved_space (inode); -return reserved_space; -} - -/* * Transfer the number of inode and blocks from one diskquota to an other. * * This operation can block, but only after everything is updated
@@ -1734,7 +1759,7 @@ int dquot_transfer(struct inode *inode, }spin_lock (&dq_data_lock); cur_space =inode_get_bytes (inode); - rsv_space =dquot_get_reserved_space (inode); + rsv_space =inode_get_rsv_space (inode); space = cur_space + rsv_space;/* Build the transfer_from list and check the limits */ for (cnt =0 ; cnt <MAXQUOTAS ; cnt++) {
include/linux/quota.h +3 -2
@@ -313,8 +313,9 @@ struct dquot_operations {int (*claim_space) (struct inode *,qsize_t );/* release rsved quota for delayed alloc */ void (*release_rsv) (struct inode *,qsize_t ); -/* get reserved quota for delayed alloc */ -qsize_t (*get_reserved_space) (struct inode *); +/* get reserved quota for delayed alloc, value returned is managed by +* quota code only */ +qsize_t *(*get_reserved_space) (struct inode *); };/* Operations handling requests from userspace */
PATCH 37/39 ext4: Convert to generic reserved quotas space management.
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dmitry Monakhov <[email protected]>
commit a9e7f4472075fb6937c545af3f6329e9946bbe66 upstream.
This patch also fixes write vs chown race condition.
--- fs/ext4/ext4.h | 6 +++++- fs/ext4/inode.c | 16 +++++++--------- fs/ext4/super.c | 5 +++++ 3 files changed, 17 insertions(+), 10 deletions(-)
fs/ext4/ext4.h +5 -1
@@ -695,6 +695,10 @@ struct ext4_inode_info {__u16 i_extra_isize;spinlock_t i_block_reservation_lock; +#ifdef CONFIG_QUOTA +/* quota space reservation, managed internally by quota code */ +qsize_t i_reserved_quota; +#endif /* completed async DIOs that might need unwritten extents handling */ struct list_head i_aio_dio_complete_list;
@@ -1439,7 +1443,7 @@ extern int ext4_chunk_trans_blocks(strucextern int ext4_block_truncate_page (handle_t *handle,struct address_space *mapping,loff_t from);extern int ext4_page_mkwrite (struct vm_area_struct *vma,struct vm_fault *vmf); -extern qsize_t ext4_get_reserved_space (struct inode *inode); +extern qsize_t *ext4_get_reserved_space (struct inode *inode);extern int flush_aio_dio_completed_IO (struct inode *inode);/* ioctl.c */ extern long ext4_ioctl (struct file *,unsigned int ,unsigned long );
fs/ext4/inode.c +7 -9
@@ -1046,17 +1046,12 @@ out:return err; } -qsize_t ext4_get_reserved_space (struct inode *inode) +#ifdef CONFIG_QUOTA +qsize_t *ext4_get_reserved_space (struct inode *inode) { -unsigned long long total; - -spin_lock (&EXT4_I (inode)->i_block_reservation_lock); - total =EXT4_I (inode)->i_reserved_data_blocks + -EXT4_I (inode)->i_reserved_meta_blocks; -spin_unlock (&EXT4_I (inode)->i_block_reservation_lock); - -return (total << inode->i_blkbits); +return &EXT4_I (inode)->i_reserved_quota; } +#endif /* * Calculate the number of metadata blocks need to reserve * to allocate @blocks for non extent file based file
@@ -4840,6 +4835,9 @@ struct inode *ext4_iget(struct super_blo ((__u64 )le16_to_cpu (raw_inode->i_file_acl_high)) <<32 ; inode->i_size =ext4_isize (raw_inode); ei->i_disksize = inode->i_size; +#ifdef CONFIG_QUOTA + ei->i_reserved_quota =0 ; +#endif inode->i_generation =le32_to_cpu (raw_inode->i_generation); ei->i_block_group = iloc.block_group; ei->i_last_alloc_group = ~0 ;
fs/ext4/super.c +5 -0
@@ -711,6 +711,9 @@ static struct inode *ext4_alloc_inode(st ei->i_allocated_meta_blocks =0 ; ei->i_delalloc_reserved_flag =0 ;spin_lock_init (&(ei->i_block_reservation_lock)); +#ifdef CONFIG_QUOTA + ei->i_reserved_quota =0 ; +#endif INIT_LIST_HEAD (&ei->i_aio_dio_complete_list); ei->cur_aio_dio =NULL ; ei->i_sync_tid =0 ;
@@ -1008,7 +1011,9 @@ static struct dquot_operations ext4_quot .reserve_space = dquot_reserve_space, .claim_space = dquot_claim_space, .release_rsv = dquot_release_reserved_space, +#ifdef CONFIG_QUOTA .get_reserved_space = ext4_get_reserved_space, +#endif .alloc_inode = dquot_alloc_inode, .free_space = dquot_free_space, .free_inode = dquot_free_inode,
PATCH 38/39 ext4: Fix potential quota deadlock
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dmitry Monakhov <[email protected]>
commit d21cd8f163ac44b15c465aab7306db931c606908 upstream.
We have to delay vfs_dq_claim_space() until allocation context destruction. Currently we have following call-trace:ext4_mb_new_blocks()
/* task is already holding ac->alloc_semp */
->ext4_mb_mark_diskspace_used
->vfs_dq_claim_space() /* acquire dqptr_sem here. Possible deadlock */
->ext4_mb_release_context() /* drop ac->alloc_semp here */
Let's move quota claiming to ext4_da_update_reserve_space()
=======================================================
[ INFO: possible circular locking dependency detected ]
2.6.32-rc7 #18
-------------------------------------------------------
write-truncate-/3465 is trying to acquire lock:
(&s->s_dquot.dqptr_sem){++++..}, at: [<c025e73b>] dquot_claim_space+0x3b/0x1b0
but task is already holding lock:
(&meta_group_info[i]->alloc_sem){++++..}, at: [<c02ce962>] ext4_mb_load_buddy+0xb2/0x370
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #3 (&meta_group_info[i]->alloc_sem){++++..}:
[<c017d04b>] __lock_acquire+0xd7b/0x1260
[<c017d5ea>] lock_acquire+0xba/0xd0
[<c0527191>] down_read+0x51/0x90
[<c02ce962>] ext4_mb_load_buddy+0xb2/0x370
[<c02d0c1c>] ext4_mb_free_blocks+0x46c/0x870
[<c029c9d3>] ext4_free_blocks+0x73/0x130
[<c02c8cfc>] ext4_ext_truncate+0x76c/0x8d0
[<c02a8087>] ext4_truncate+0x187/0x5e0
[<c01e0f7b>] vmtruncate+0x6b/0x70
[<c022ec02>] inode_setattr+0x62/0x190
[<c02a2d7a>] ext4_setattr+0x25a/0x370
[<c022ee81>] notify_change+0x151/0x340
[<c021349d>] do_truncate+0x6d/0xa0
[<c0221034>] may_open+0x1d4/0x200
[<c022412b>] do_filp_open+0x1eb/0x910
[<c021244d>] do_sys_open+0x6d/0x140
[<c021258e>] sys_open+0x2e/0x40
[<c0103100>] sysenter_do_call+0x12/0x32-> #2 (&ei->i_data_sem){++++..}:
[<c017d04b>] __lock_acquire+0xd7b/0x1260
[<c017d5ea>] lock_acquire+0xba/0xd0
[<c0527191>] down_read+0x51/0x90
[<c02a5787>] ext4_get_blocks+0x47/0x450
[<c02a74c1>] ext4_getblk+0x61/0x1d0
[<c02a7a7f>] ext4_bread+0x1f/0xa0
[<c02bcddc>] ext4_quota_write+0x12c/0x310
[<c0262d23>] qtree_write_dquot+0x93/0x120
[<c0261708>] v2_write_dquot+0x28/0x30
[<c025d3fb>] dquot_commit+0xab/0xf0
[<c02be977>] ext4_write_dquot+0x77/0x90
[<c02be9bf>] ext4_mark_dquot_dirty+0x2f/0x50
[<c025e321>] dquot_alloc_inode+0x101/0x180
[<c029fec2>] ext4_new_inode+0x602/0xf00
[<c02ad789>] ext4_create+0x89/0x150
[<c0221ff2>] vfs_create+0xa2/0xc0
[<c02246e7>] do_filp_open+0x7a7/0x910
[<c021244d>] do_sys_open+0x6d/0x140
[<c021258e>] sys_open+0x2e/0x40
[<c0103100>] sysenter_do_call+0x12/0x32-> #1 (&sb->s_type->i_mutex_key#7/4){+.+...}:
[<c017d04b>] __lock_acquire+0xd7b/0x1260
[<c017d5ea>] lock_acquire+0xba/0xd0
[<c0526505>] mutex_lock_nested+0x65/0x2d0
[<c0260c9d>] vfs_load_quota_inode+0x4bd/0x5a0
[<c02610af>] vfs_quota_on_path+0x5f/0x70
[<c02bc812>] ext4_quota_on+0x112/0x190
[<c026345a>] sys_quotactl+0x44a/0x8a0
[<c0103100>] sysenter_do_call+0x12/0x32-> #0 (&s->s_dquot.dqptr_sem){++++..}:
[<c017d361>] __lock_acquire+0x1091/0x1260
[<c017d5ea>] lock_acquire+0xba/0xd0
[<c0527191>] down_read+0x51/0x90
[<c025e73b>] dquot_claim_space+0x3b/0x1b0
[<c02cb95f>] ext4_mb_mark_diskspace_used+0x36f/0x380
[<c02d210a>] ext4_mb_new_blocks+0x34a/0x530
[<c02c83fb>] ext4_ext_get_blocks+0x122b/0x13c0
[<c02a5966>] ext4_get_blocks+0x226/0x450
[<c02a5ff3>] mpage_da_map_blocks+0xc3/0xaa0
[<c02a6ed6>] ext4_da_writepages+0x506/0x790
[<c01de272>] do_writepages+0x22/0x50
[<c01d766d>] __filemap_fdatawrite_range+0x6d/0x80
[<c01d7b9b>] filemap_flush+0x2b/0x30
[<c02a40ac>] ext4_alloc_da_blocks+0x5c/0x60
[<c029e595>] ext4_release_file+0x75/0xb0
[<c0216b59>] __fput+0xf9/0x210
[<c0216c97>] fput+0x27/0x30
[<c02122dc>] filp_close+0x4c/0x80
[<c014510e>] put_files_struct+0x6e/0xd0
[<c01451b7>] exit_files+0x47/0x60
[<c0146a24>] do_exit+0x144/0x710
[<c0147028>] do_group_exit+0x38/0xa0
[<c0159abc>] get_signal_to_deliver+0x2ac/0x410
[<c0102849>] do_notify_resume+0xb9/0x890
[<c01032d2>] work_notifysig+0x13/0x21other info that might help us debug this:
3 locks held by write-truncate-/3465:
#0: (jbd2_handle){+.+...}, at: [<c02e1f8f>] start_this_handle+0x38f/0x5c0
#1: (&ei->i_data_sem){++++..}, at: [<c02a57f6>] ext4_get_blocks+0xb6/0x450
#2: (&meta_group_info[i]->alloc_sem){++++..}, at: [<c02ce962>] ext4_mb_load_buddy+0xb2/0x370stack backtrace: Pid: 3465, comm: write-truncate- Not tainted 2.6.32-rc7 #18 Call Trace: [<c0524cb3>] ? printk+0x1d/0x22 [<c017ac9a>] print_circular_bug+0xca/0xd0 [<c017d361>] __lock_acquire+0x1091/0x1260 [<c016bca2>] ? sched_clock_local+0xd2/0x170 [<c0178fd0>] ? trace_hardirqs_off_caller+0x20/0xd0 [<c017d5ea>] lock_acquire+0xba/0xd0 [<c025e73b>] ? dquot_claim_space+0x3b/0x1b0 [<c0527191>] down_read+0x51/0x90 [<c025e73b>] ? dquot_claim_space+0x3b/0x1b0 [<c025e73b>] dquot_claim_space+0x3b/0x1b0 [<c02cb95f>] ext4_mb_mark_diskspace_used+0x36f/0x380 [<c02d210a>] ext4_mb_new_blocks+0x34a/0x530 [<c02c601d>] ? ext4_ext_find_extent+0x25d/0x280 [<c02c83fb>] ext4_ext_get_blocks+0x122b/0x13c0 [<c016bca2>] ? sched_clock_local+0xd2/0x170 [<c016be60>] ? sched_clock_cpu+0x120/0x160 [<c016beef>] ? cpu_clock+0x4f/0x60 [<c0178fd0>] ? trace_hardirqs_off_caller+0x20/0xd0 [<c052712c>] ? down_write+0x8c/0xa0 [<c02a5966>] ext4_get_blocks+0x226/0x450 [<c016be60>] ? sched_clock_cpu+0x120/0x160 [<c016beef>] ? cpu_clock+0x4f/0x60 [<c017908b>] ? trace_hardirqs_off+0xb/0x10 [<c02a5ff3>] mpage_da_map_blocks+0xc3/0xaa0 [<c01d69cc>] ? find_get_pages_tag+0x16c/0x180 [<c01d6860>] ? find_get_pages_tag+0x0/0x180 [<c02a73bd>] ? __mpage_da_writepage+0x16d/0x1a0 [<c01dfc4e>] ? pagevec_lookup_tag+0x2e/0x40 [<c01ddf1b>] ? write_cache_pages+0xdb/0x3d0 [<c02a7250>] ? __mpage_da_writepage+0x0/0x1a0 [<c02a6ed6>] ext4_da_writepages+0x506/0x790 [<c016beef>] ? cpu_clock+0x4f/0x60 [<c016bca2>] ? sched_clock_local+0xd2/0x170 [<c016be60>] ? sched_clock_cpu+0x120/0x160 [<c016be60>] ? sched_clock_cpu+0x120/0x160 [<c02a69d0>] ? ext4_da_writepages+0x0/0x790 [<c01de272>] do_writepages+0x22/0x50 [<c01d766d>] __filemap_fdatawrite_range+0x6d/0x80 [<c01d7b9b>] filemap_flush+0x2b/0x30 [<c02a40ac>] ext4_alloc_da_blocks+0x5c/0x60 [<c029e595>] ext4_release_file+0x75/0xb0 [<c0216b59>] __fput+0xf9/0x210 [<c0216c97>] fput+0x27/0x30 [<c02122dc>] filp_close+0x4c/0x80 [<c014510e>] put_files_struct+0x6e/0xd0 [<c01451b7>] exit_files+0x47/0x60 [<c0146a24>] do_exit+0x144/0x710 [<c017b163>] ? lock_release_holdtime+0x33/0x210 [<c0528137>] ? _spin_unlock_irq+0x27/0x30 [<c0147028>] do_group_exit+0x38/0xa0 [<c017babb>] ? trace_hardirqs_on+0xb/0x10 [<c0159abc>] get_signal_to_deliver+0x2ac/0x410 [<c0102849>] do_notify_resume+0xb9/0x890 [<c0178fd0>] ? trace_hardirqs_off_caller+0x20/0xd0 [<c017b163>] ? lock_release_holdtime+0x33/0x210 [<c0165b50>] ? autoremove_wake_function+0x0/0x50 [<c017ba54>] ? trace_hardirqs_on_caller+0x134/0x190 [<c017babb>] ? trace_hardirqs_on+0xb/0x10 [<c0300ba4>] ? security_file_permission+0x14/0x20 [<c0215761>] ? vfs_write+0x131/0x190 [<c0214f50>] ? do_sync_write+0x0/0x120 [<c0103115>] ? sysenter_do_call+0x27/0x32 [<c01032d2>] work_notifysig+0x13/0x21
--- fs/ext4/inode.c | 9 +++++++-- fs/ext4/mballoc.c | 6 ------ 2 files changed, 7 insertions(+), 8 deletions(-)
fs/ext4/inode.c +7 -2
@@ -1089,7 +1089,7 @@ static int ext4_calc_metadata_amount(strstatic void ext4_da_update_reserve_space (struct inode *inode,int used) {struct ext4_sb_info *sbi =EXT4_SB (inode->i_sb); -int total, mdb, mdb_free; +int total, mdb, mdb_free, mdb_claim =0 ;spin_lock (&EXT4_I (inode)->i_block_reservation_lock);/* recalculate the number of metablocks still need to be reserved */
@@ -1102,7 +1102,9 @@ static void ext4_da_update_reserve_spaceif (mdb_free) {/* Account for allocated meta_blocks */ - mdb_free -=EXT4_I (inode)->i_allocated_meta_blocks; + mdb_claim =EXT4_I (inode)->i_allocated_meta_blocks; +BUG_ON (mdb_free < mdb_claim); + mdb_free -= mdb_claim;/* update fs dirty blocks counter */ percpu_counter_sub (&sbi->s_dirtyblocks_counter, mdb_free);
@@ -1113,8 +1115,11 @@ static void ext4_da_update_reserve_space/* update per-inode reservations */ BUG_ON (used >EXT4_I (inode)->i_reserved_data_blocks);EXT4_I (inode)->i_reserved_data_blocks -= used; +percpu_counter_sub (&sbi->s_dirtyblocks_counter, used + mdb_claim);spin_unlock (&EXT4_I (inode)->i_block_reservation_lock); +vfs_dq_claim_block (inode, used + mdb_claim); +/* * free those over-booking quota for metadata blocks */
fs/ext4/mballoc.c +0 -6
@@ -3000,12 +3000,6 @@ ext4_mb_mark_diskspace_used(struct ext4_if (!(ac->ac_flags &EXT4_MB_DELALLOC_RESERVED ))/* release all the reserved blocks if non delalloc */ percpu_counter_sub (&sbi->s_dirtyblocks_counter, reserv_blks); -else { -percpu_counter_sub (&sbi->s_dirtyblocks_counter, - ac->ac_b_ex.fe_len); -/* convert reserved quota blocks to real quota blocks */ -vfs_dq_claim_block (ac->ac_inode, ac->ac_b_ex.fe_len); - }if (sbi->s_log_groups_per_flex) { ext4_group_t flex_group = ext4_flex_group(sbi,
PATCH 39/39 ext4: fix sleep inside spinlock issue with quota and dealloc (#14739)
In reply to Greg KH2.6.31-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dmitry Monakhov <[email protected]>
commit 39bc680a8160bb9d6743f7873b535d553ff61058 upstream.
Unlock i_block_reservation_lock before vfs_dq_reserve_block(). This patch fixes http://bugzilla.kernel.org/show_bug.cgi?id=14739
--- fs/ext4/inode.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
fs/ext4/inode.c +5 -6
@@ -1859,19 +1859,17 @@ repeat: md_needed = mdblocks -EXT4_I (inode)->i_reserved_meta_blocks; total = md_needed + nrblocks; +spin_unlock (&EXT4_I (inode)->i_block_reservation_lock);/* * Make quota reservation here to prevent quota overflow * later. Real quota accounting is done at pages writeout * time. */ -if (vfs_dq_reserve_block (inode, total)) { -spin_unlock (&EXT4_I (inode)->i_block_reservation_lock); +if (vfs_dq_reserve_block (inode, total))return -EDQUOT ; - }if (ext4_claim_free_blocks (sbi, total)) { -spin_unlock (&EXT4_I (inode)->i_block_reservation_lock);vfs_dq_release_reservation_block (inode, total);if (ext4_should_retry_alloc (inode->i_sb, &retries)) {yield ();
@@ -1879,10 +1877,11 @@ repeat: }return -ENOSPC ; } +spin_lock (&EXT4_I (inode)->i_block_reservation_lock);EXT4_I (inode)->i_reserved_data_blocks += nrblocks; -EXT4_I (inode)->i_reserved_meta_blocks = mdblocks; - +EXT4_I (inode)->i_reserved_meta_blocks += md_needed;spin_unlock (&EXT4_I (inode)->i_block_reservation_lock); +return 0 ;/* success */ }