* [PATCH net 1/3] enic: unlock napi busy poll before unmasking intr
@ 2015-06-11 6:22 Govindarajulu Varadarajan
2015-06-11 6:22 ` [PATCH net 2/3] enic: check return value for stat dump Govindarajulu Varadarajan
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Govindarajulu Varadarajan @ 2015-06-11 6:22 UTC (permalink / raw)
To: davem, netdev; +Cc: ssujith, benve, Govindarajulu Varadarajan
There is a small window between vnic_intr_unmask() and enic_poll_unlock_napi().
In this window if an irq occurs and napi is scheduled on different cpu, it tries
to acquire enic_poll_lock_napi() and hits the following WARN_ON message.
Fix is to unlock napi_poll before unmasking the interrupt.
[ 781.121746] ------------[ cut here ]------------
[ 781.121789] WARNING: CPU: 1 PID: 0 at drivers/net/ethernet/cisco/enic/vnic_rq.h:228 enic_poll_msix_rq+0x36a/0x3c0 [enic]()
[ 781.121834] Modules linked in: nfsv3 nfs_acl rpcsec_gss_krb5 auth_rpcgss oid_registry nfsv4 dns_resolver coretemp intel_rapl iosf_mbi x86_pkg_temp_thermal intel_powerclamp kvm_intel kvm crct10dif_pclmul crc32_pclmul ghash_clmulni_intel aesni_intel mgag200 ttm drm_kms_helper joydev aes_x86_64 lrw drm gf128mul mousedev glue_helper sb_edac ablk_helper iTCO_wdt iTCO_vendor_support evdev ipmi_si syscopyarea sysfillrect sysimgblt i2c_algo_bit i2c_core edac_core lpc_ich mac_hid cryptd pcspkr ipmi_msghandler shpchp tpm_tis acpi_power_meter tpm wmi processor hwmon button ac sch_fq_codel nfs lockd grace sunrpc fscache hid_generic usbhid hid ehci_pci ehci_hcd sd_mod megaraid_sas usbcore scsi_mod usb_common enic crc32c_generic crc32c_intel btrfs xor raid6_pq ext4 crc16 mbcache jbd2
[ 781.122176] CPU: 1 PID: 0 Comm: swapper/1 Not tainted 4.1.0-rc6-ARCH-00040-gc46a024-dirty #106
[ 781.122210] Hardware name: Cisco Systems Inc UCSB-B200-M4/UCSB-B200-M4, BIOS B200M4.2.2.2.23.061220140128 06/12/2014
[ 781.122252] 0000000000000000 bddbbc9d655ec96e ffff880277e43da8 ffffffff81583fe8
[ 781.122286] 0000000000000000 0000000000000000 ffff880277e43de8 ffffffff8107acfa
[ 781.122319] ffff880272c01000 ffff880273f18000 ffff880273f1a100 0000000000000000
[ 781.122352] Call Trace:
[ 781.122364] <IRQ> [<ffffffff81583fe8>] dump_stack+0x4f/0x7b
[ 781.122399] [<ffffffff8107acfa>] warn_slowpath_common+0x8a/0xc0
[ 781.122425] [<ffffffff8107ae2a>] warn_slowpath_null+0x1a/0x20
[ 781.122455] [<ffffffffa01fa9ca>] enic_poll_msix_rq+0x36a/0x3c0 [enic]
[ 781.122487] [<ffffffff8148525a>] net_rx_action+0x22a/0x370
[ 781.122512] [<ffffffff8107ed3d>] __do_softirq+0xed/0x2d0
[ 781.122537] [<ffffffff8107f06e>] irq_exit+0x7e/0xa0
[ 781.122560] [<ffffffff8158c424>] do_IRQ+0x64/0x100
[ 781.122582] [<ffffffff8158a42e>] common_interrupt+0x6e/0x6e
[ 781.122605] <EOI> [<ffffffff810bd331>] ? cpu_startup_entry+0x121/0x480
[ 781.122638] [<ffffffff810bd2fc>] ? cpu_startup_entry+0xec/0x480
[ 781.122667] [<ffffffff810f2ed3>] ? clockevents_register_device+0x113/0x1f0
[ 781.122698] [<ffffffff81050ab6>] start_secondary+0x196/0x1e0
[ 781.122723] ---[ end trace cec2e9dd3af7b9db ]---
Signed-off-by: Govindarajulu Varadarajan <_govind@gmx.com>
---
drivers/net/ethernet/cisco/enic/enic_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index 204bd182..0e5a01d 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -1407,6 +1407,7 @@ static int enic_poll_msix_rq(struct napi_struct *napi, int budget)
*/
enic_calc_int_moderation(enic, &enic->rq[rq]);
+ enic_poll_unlock_napi(&enic->rq[rq]);
if (work_done < work_to_do) {
/* Some work done, but not enough to stay in polling,
@@ -1418,7 +1419,6 @@ static int enic_poll_msix_rq(struct napi_struct *napi, int budget)
enic_set_int_moderation(enic, &enic->rq[rq]);
vnic_intr_unmask(&enic->intr[intr]);
}
- enic_poll_unlock_napi(&enic->rq[rq]);
return work_done;
}
--
2.4.2
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH net 2/3] enic: check return value for stat dump
2015-06-11 6:22 [PATCH net 1/3] enic: unlock napi busy poll before unmasking intr Govindarajulu Varadarajan
@ 2015-06-11 6:22 ` Govindarajulu Varadarajan
2015-06-11 6:43 ` David Miller
2015-06-11 6:22 ` [PATCH net 3/3] enic: fix memory leak in rq_clean Govindarajulu Varadarajan
2015-06-11 6:43 ` [PATCH net 1/3] enic: unlock napi busy poll before unmasking intr David Miller
2 siblings, 1 reply; 6+ messages in thread
From: Govindarajulu Varadarajan @ 2015-06-11 6:22 UTC (permalink / raw)
To: davem, netdev; +Cc: ssujith, benve, Govindarajulu Varadarajan
We do not check the return value of enic_dev_stats_dump(). If allocation
fails, we will hit NULL pointer reference.
Return only if memory allocation fails. For other failures, we return the
previously recorded values.
Signed-off-by: Govindarajulu Varadarajan <_govind@gmx.com>
---
drivers/net/ethernet/cisco/enic/enic_ethtool.c | 20 +++++++++++++++++---
drivers/net/ethernet/cisco/enic/enic_main.c | 9 ++++++++-
2 files changed, 25 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/cisco/enic/enic_ethtool.c b/drivers/net/ethernet/cisco/enic/enic_ethtool.c
index 28d9ca6..68d47b1 100644
--- a/drivers/net/ethernet/cisco/enic/enic_ethtool.c
+++ b/drivers/net/ethernet/cisco/enic/enic_ethtool.c
@@ -131,8 +131,15 @@ static void enic_get_drvinfo(struct net_device *netdev,
{
struct enic *enic = netdev_priv(netdev);
struct vnic_devcmd_fw_info *fw_info;
+ int err;
- enic_dev_fw_info(enic, &fw_info);
+ err = enic_dev_fw_info(enic, &fw_info);
+ /* return only when pci_zalloc_consistent fails in vnic_dev_fw_info
+ * For other failures, like devcmd failure, we return previously
+ * recorded info.
+ */
+ if (err == -ENOMEM)
+ return;
strlcpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
strlcpy(drvinfo->version, DRV_VERSION, sizeof(drvinfo->version));
@@ -181,8 +188,15 @@ static void enic_get_ethtool_stats(struct net_device *netdev,
struct enic *enic = netdev_priv(netdev);
struct vnic_stats *vstats;
unsigned int i;
-
- enic_dev_stats_dump(enic, &vstats);
+ int err;
+
+ err = enic_dev_stats_dump(enic, &vstats);
+ /* return only when pci_zalloc_consistent fails in vnic_dev_stats_dump
+ * For other failures, like devcmd failure, we return previously
+ * recorded stats.
+ */
+ if (err == -ENOMEM)
+ return;
for (i = 0; i < enic_n_tx_stats; i++)
*(data++) = ((u64 *)&vstats->tx)[enic_tx_stats[i].index];
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index 0e5a01d..eadae1b 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -615,8 +615,15 @@ static struct rtnl_link_stats64 *enic_get_stats(struct net_device *netdev,
{
struct enic *enic = netdev_priv(netdev);
struct vnic_stats *stats;
+ int err;
- enic_dev_stats_dump(enic, &stats);
+ err = enic_dev_stats_dump(enic, &stats);
+ /* return only when pci_zalloc_consistent fails in vnic_dev_stats_dump
+ * For other failures, like devcmd failure, we return previously
+ * recorded stats.
+ */
+ if (err == -ENOMEM)
+ return net_stats;
net_stats->tx_packets = stats->tx.tx_frames_ok;
net_stats->tx_bytes = stats->tx.tx_bytes_ok;
--
2.4.2
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH net 3/3] enic: fix memory leak in rq_clean
2015-06-11 6:22 [PATCH net 1/3] enic: unlock napi busy poll before unmasking intr Govindarajulu Varadarajan
2015-06-11 6:22 ` [PATCH net 2/3] enic: check return value for stat dump Govindarajulu Varadarajan
@ 2015-06-11 6:22 ` Govindarajulu Varadarajan
2015-06-11 6:43 ` David Miller
2015-06-11 6:43 ` [PATCH net 1/3] enic: unlock napi busy poll before unmasking intr David Miller
2 siblings, 1 reply; 6+ messages in thread
From: Govindarajulu Varadarajan @ 2015-06-11 6:22 UTC (permalink / raw)
To: davem, netdev; +Cc: ssujith, benve, Govindarajulu Varadarajan
When incoming packet qualifies for rx_copybreak, we copy the data to newly
allocated skb. We do not free/unmap the original buffer. At this point driver
assumes this buffer is unallocated. When enic_rq_alloc_buf() is called for
buffer allocation, it checks if buf->os_buf is NULL. If its not NULL that means
buffer can be re-used.
When vnic_rq_clean() is called for freeing all rq buffers, and if the
rx_copybreak reused buffer falls outside the used desc, we do not free the
buffer. The following trace is observer when dma-debug is enabled.
Fix is to walk through complete ring and clean if buffer is present.
[ 40.555386] ------------[ cut here ]------------
[ 40.555396] WARNING: CPU: 0 PID: 491 at lib/dma-debug.c:971 dma_debug_device_change+0x188/0x1f0()
[ 40.555400] pci 0000:06:00.0: DMA-API: device driver has pending DMA allocations while released from device [count=4]
One of leaked entries details: [device address=0x00000000ff4cc040] [size=9018 bytes] [mapped with DMA_FROM_DEVICE] [mapped as single]
[ 40.555402] Modules linked in: nfsv3 nfs_acl rpcsec_gss_krb5 auth_rpcgss oid_registry nfsv4 dns_resolver coretemp intel_rapl iosf_mbi x86_pkg_temp_thermal intel_powerclamp kvm_intel kvm crct10dif_pclmul crc32_pclmul ghash_clmulni_intel aesni_intel aes_x86_64 lrw joydev mousedev gf128mul hid_generic glue_helper mgag200 usbhid ttm hid drm_kms_helper drm ablk_helper syscopyarea sysfillrect sysimgblt i2c_algo_bit i2c_core iTCO_wdt cryptd mac_hid evdev pcspkr sb_edac edac_core tpm_tis iTCO_vendor_support ipmi_si wmi tpm ipmi_msghandler shpchp lpc_ich processor acpi_power_meter hwmon button ac sch_fq_codel nfs lockd grace sunrpc fscache sd_mod ehci_pci ehci_hcd megaraid_sas usbcore scsi_mod usb_common enic(-) crc32c_generic crc32c_intel btrfs xor raid6_pq ext4 crc16 mbcache jbd2
[ 40.555467] CPU: 0 PID: 491 Comm: rmmod Not tainted 4.1.0-rc7-ARCH-01305-gf59b71f #118
[ 40.555469] Hardware name: Cisco Systems Inc UCSB-B200-M4/UCSB-B200-M4, BIOS B200M4.2.2.2.23.061220140128 06/12/2014
[ 40.555471] 0000000000000000 00000000e2f8a5b7 ffff880275f8bc48 ffffffff8158d6f0
[ 40.555474] 0000000000000000 ffff880275f8bca0 ffff880275f8bc88 ffffffff8107b04a
[ 40.555477] ffff8802734e0000 0000000000000004 ffff8804763fb3c0 ffff88027600b650
[ 40.555480] Call Trace:
[ 40.555488] [<ffffffff8158d6f0>] dump_stack+0x4f/0x7b
[ 40.555492] [<ffffffff8107b04a>] warn_slowpath_common+0x8a/0xc0
[ 40.555494] [<ffffffff8107b0d5>] warn_slowpath_fmt+0x55/0x70
[ 40.555498] [<ffffffff812fa408>] dma_debug_device_change+0x188/0x1f0
[ 40.555503] [<ffffffff8109aaef>] notifier_call_chain+0x4f/0x80
[ 40.555506] [<ffffffff8109aecb>] __blocking_notifier_call_chain+0x4b/0x70
[ 40.555510] [<ffffffff8109af06>] blocking_notifier_call_chain+0x16/0x20
[ 40.555514] [<ffffffff813f8066>] __device_release_driver+0xf6/0x120
[ 40.555518] [<ffffffff813f8b08>] driver_detach+0xc8/0xd0
[ 40.555523] [<ffffffff813f7c59>] bus_remove_driver+0x59/0xe0
[ 40.555527] [<ffffffff813f93a0>] driver_unregister+0x30/0x70
[ 40.555534] [<ffffffff8131532d>] pci_unregister_driver+0x2d/0xa0
[ 40.555542] [<ffffffffa0200ec2>] enic_cleanup_module+0x10/0x14e [enic]
[ 40.555547] [<ffffffff8110158f>] SyS_delete_module+0x1cf/0x280
[ 40.555551] [<ffffffff811e284e>] ? ____fput+0xe/0x10
[ 40.555554] [<ffffffff810980ec>] ? task_work_run+0xbc/0xf0
[ 40.555558] [<ffffffff815930ee>] system_call_fastpath+0x12/0x71
[ 40.555561] ---[ end trace 4988cadc77c2b236 ]---
[ 40.555562] Mapped at:
[ 40.555563] [<ffffffff812fa865>] debug_dma_map_page+0x95/0x150
[ 40.555566] [<ffffffffa01f4a88>] enic_rq_alloc_buf+0x1b8/0x360 [enic]
[ 40.555570] [<ffffffffa01f7658>] enic_open+0xf8/0x820 [enic]
[ 40.555574] [<ffffffff8148d50e>] __dev_open+0xce/0x150
[ 40.555579] [<ffffffff8148d851>] __dev_change_flags+0xa1/0x170
Signed-off-by: Govindarajulu Varadarajan <_govind@gmx.com>
---
drivers/net/ethernet/cisco/enic/vnic_rq.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/cisco/enic/vnic_rq.c b/drivers/net/ethernet/cisco/enic/vnic_rq.c
index 36a2ed6..c4b2183 100644
--- a/drivers/net/ethernet/cisco/enic/vnic_rq.c
+++ b/drivers/net/ethernet/cisco/enic/vnic_rq.c
@@ -188,16 +188,15 @@ void vnic_rq_clean(struct vnic_rq *rq,
struct vnic_rq_buf *buf;
u32 fetch_index;
unsigned int count = rq->ring.desc_count;
+ int i;
buf = rq->to_clean;
- while (vnic_rq_desc_used(rq) > 0) {
-
+ for (i = 0; i < rq->ring.desc_count; i++) {
(*buf_clean)(rq, buf);
-
- buf = rq->to_clean = buf->next;
- rq->ring.desc_avail++;
+ buf = buf->next;
}
+ rq->ring.desc_avail = rq->ring.desc_count - 1;
/* Use current fetch_index as the ring starting point */
fetch_index = ioread32(&rq->ctrl->fetch_index);
--
2.4.2
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH net 1/3] enic: unlock napi busy poll before unmasking intr
2015-06-11 6:22 [PATCH net 1/3] enic: unlock napi busy poll before unmasking intr Govindarajulu Varadarajan
2015-06-11 6:22 ` [PATCH net 2/3] enic: check return value for stat dump Govindarajulu Varadarajan
2015-06-11 6:22 ` [PATCH net 3/3] enic: fix memory leak in rq_clean Govindarajulu Varadarajan
@ 2015-06-11 6:43 ` David Miller
2 siblings, 0 replies; 6+ messages in thread
From: David Miller @ 2015-06-11 6:43 UTC (permalink / raw)
To: _govind; +Cc: netdev, ssujith, benve
From: Govindarajulu Varadarajan <_govind@gmx.com>
Date: Thu, 11 Jun 2015 11:52:54 +0530
> There is a small window between vnic_intr_unmask() and enic_poll_unlock_napi().
> In this window if an irq occurs and napi is scheduled on different cpu, it tries
> to acquire enic_poll_lock_napi() and hits the following WARN_ON message.
>
> Fix is to unlock napi_poll before unmasking the interrupt.
...
> Signed-off-by: Govindarajulu Varadarajan <_govind@gmx.com>
Applied.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH net 2/3] enic: check return value for stat dump
2015-06-11 6:22 ` [PATCH net 2/3] enic: check return value for stat dump Govindarajulu Varadarajan
@ 2015-06-11 6:43 ` David Miller
0 siblings, 0 replies; 6+ messages in thread
From: David Miller @ 2015-06-11 6:43 UTC (permalink / raw)
To: _govind; +Cc: netdev, ssujith, benve
From: Govindarajulu Varadarajan <_govind@gmx.com>
Date: Thu, 11 Jun 2015 11:52:55 +0530
> We do not check the return value of enic_dev_stats_dump(). If allocation
> fails, we will hit NULL pointer reference.
>
> Return only if memory allocation fails. For other failures, we return the
> previously recorded values.
>
> Signed-off-by: Govindarajulu Varadarajan <_govind@gmx.com>
Applied.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH net 3/3] enic: fix memory leak in rq_clean
2015-06-11 6:22 ` [PATCH net 3/3] enic: fix memory leak in rq_clean Govindarajulu Varadarajan
@ 2015-06-11 6:43 ` David Miller
0 siblings, 0 replies; 6+ messages in thread
From: David Miller @ 2015-06-11 6:43 UTC (permalink / raw)
To: _govind; +Cc: netdev, ssujith, benve
From: Govindarajulu Varadarajan <_govind@gmx.com>
Date: Thu, 11 Jun 2015 11:52:56 +0530
> When incoming packet qualifies for rx_copybreak, we copy the data to newly
> allocated skb. We do not free/unmap the original buffer. At this point driver
> assumes this buffer is unallocated. When enic_rq_alloc_buf() is called for
> buffer allocation, it checks if buf->os_buf is NULL. If its not NULL that means
> buffer can be re-used.
>
> When vnic_rq_clean() is called for freeing all rq buffers, and if the
> rx_copybreak reused buffer falls outside the used desc, we do not free the
> buffer. The following trace is observer when dma-debug is enabled.
>
> Fix is to walk through complete ring and clean if buffer is present.
...
> Signed-off-by: Govindarajulu Varadarajan <_govind@gmx.com>
Applied.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2015-06-11 6:43 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-06-11 6:22 [PATCH net 1/3] enic: unlock napi busy poll before unmasking intr Govindarajulu Varadarajan
2015-06-11 6:22 ` [PATCH net 2/3] enic: check return value for stat dump Govindarajulu Varadarajan
2015-06-11 6:43 ` David Miller
2015-06-11 6:22 ` [PATCH net 3/3] enic: fix memory leak in rq_clean Govindarajulu Varadarajan
2015-06-11 6:43 ` David Miller
2015-06-11 6:43 ` [PATCH net 1/3] enic: unlock napi busy poll before unmasking intr David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).