* Re: [PATCH] cnic: Fix ISCSI_KEVENT_IF_DOWN message handling.
From: Mike Christie @ 2009-07-29 8:17 UTC (permalink / raw)
To: Michael Chan
Cc: davem@davemloft.net, James.Bottomley@HansenPartnership.com,
netdev@vger.kernel.org, linux-scsi@vger.kernel.org,
open-iscsi@googlegroups.com
In-Reply-To: <C27F8246C663564A84BB7AB343977242178EE780E1@IRVEXCHCCR01.corp.ad.broadcom.com>
Michael Chan wrote:
> Mike Christie wrote:
>
>> Michael Chan wrote:
>>> When a net device goes down or when the bnx2i driver is unloaded,
>>> the code was not generating the ISCSI_KEVENT_IF_DOWN message
>>> properly and this could cause the userspace driver to crash.
>>>
>>> This is fixed by sending the message properly in the shutdown path.
>>> cnic_uio_stop() is also added to send the message when bnx2i is
>>> unregistering.
>>>
>>> Signed-off-by: Michael Chan <mchan@broadcom.com>
>>> ---
>>> drivers/net/cnic.c | 23 +++++++++++++++++++++--
>>> 1 files changed, 21 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
>>> index 4d1515f..4869d77 100644
>>> --- a/drivers/net/cnic.c
>>> +++ b/drivers/net/cnic.c
>>> @@ -227,7 +227,7 @@ static int cnic_send_nlmsg(struct
>> cnic_local *cp, u32 type,
>>> }
>>>
>>> rcu_read_lock();
>>> - ulp_ops = rcu_dereference(cp->ulp_ops[CNIC_ULP_ISCSI]);
>>> + ulp_ops = rcu_dereference(cnic_ulp_tbl[CNIC_ULP_ISCSI]);
>>> if (ulp_ops)
>>> ulp_ops->iscsi_nl_send_msg(cp->dev, msg_type, buf, len);
>>> rcu_read_unlock();
>>> @@ -319,6 +319,20 @@ static int cnic_abort_prep(struct
>> cnic_sock *csk)
>>> return 0;
>>> }
>>>
>>> +static void cnic_uio_stop(void)
>>> +{
>>> + struct cnic_dev *dev;
>>> +
>>> + read_lock(&cnic_dev_lock);
>>> + list_for_each_entry(dev, &cnic_dev_list, list) {
>>> + struct cnic_local *cp = dev->cnic_priv;
>>> +
>>> + if (cp->cnic_uinfo)
>>> + cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL);
>> I don't think you can call this with the cnic_dev_lock held.
>> They have
>> the same sleeping restrictions as a spin_lock right? If so,
>> the problem
>> is that iscsi_nl_send_ms calls iscsi_offload_mesg which uses GFP_NOIO
>> and can sleep.
>>
>>
> In that case, can I send in a patch to change iscsi_offload_mesg() to
> use GFP_ATOMIC?
>
Yes, I guess so.
^ permalink raw reply
* [PATCH] gianfar: fix coalescing setup in ethtool support
From: Li Yang @ 2009-07-29 8:51 UTC (permalink / raw)
To: davem; +Cc: netdev, linuxppc-dev, Jiajun Wu, Li Yang
From: Jiajun Wu <b06378@freescale.com>
Parameter order for using mk_ic_value(count, time) was reversed,
the patch fixes this.
Signed-off-by: Jiajun Wu <b06378@freescale.com>
Signed-off-by: Li Yang <leoli@freescale.com>
---
drivers/net/gianfar_ethtool.c | 10 ++++------
1 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c
index 2a7edfa..3109f4b 100644
--- a/drivers/net/gianfar_ethtool.c
+++ b/drivers/net/gianfar_ethtool.c
@@ -373,9 +373,8 @@ static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals
return -EINVAL;
}
- priv->rxic = mk_ic_value(
- gfar_usecs2ticks(priv, cvals->rx_coalesce_usecs),
- cvals->rx_max_coalesced_frames);
+ priv->rxic = mk_ic_value(cvals->rx_max_coalesced_frames,
+ gfar_usecs2ticks(priv, cvals->rx_coalesce_usecs));
/* Set up tx coalescing */
if ((cvals->tx_coalesce_usecs == 0) ||
@@ -397,9 +396,8 @@ static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals
return -EINVAL;
}
- priv->txic = mk_ic_value(
- gfar_usecs2ticks(priv, cvals->tx_coalesce_usecs),
- cvals->tx_max_coalesced_frames);
+ priv->txic = mk_ic_value(cvals->tx_max_coalesced_frames,
+ gfar_usecs2ticks(priv, cvals->tx_coalesce_usecs));
gfar_write(&priv->regs->rxic, 0);
if (priv->rxcoalescing)
--
1.5.6.3
^ permalink raw reply related
* [PATCH V3] CAN: Add Flexcan CAN controller driver
From: Sascha Hauer @ 2009-07-29 8:20 UTC (permalink / raw)
To: Linux Netdev List; +Cc: Socketcan-core
And another go...
Sascha
>From 9f6f6fb67d57d082e056dec8121f1423c1b4fa0b Mon Sep 17 00:00:00 2001
From: Sascha Hauer <s.hauer@pengutronix.de>
Date: Tue, 21 Jul 2009 10:47:19 +0200
Subject: [PATCH] CAN: Add Flexcan CAN driver
This core is found on some Freescale SoCs and also some Coldfire
SoCs. Support for Coldfire is missing though at the moment as
they have an older revision of the core which does not have RX FIFO
support.
V3: integrated comments from Oliver Hartkopp
V2: integrated comments from Wolfgang Grandegger
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/net/can/Kconfig | 6 +
drivers/net/can/Makefile | 1 +
drivers/net/can/flexcan.c | 719 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 726 insertions(+), 0 deletions(-)
create mode 100644 drivers/net/can/flexcan.c
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
index 33821a8..99c6da4 100644
--- a/drivers/net/can/Kconfig
+++ b/drivers/net/can/Kconfig
@@ -74,6 +74,12 @@ config CAN_KVASER_PCI
This driver is for the the PCIcanx and PCIcan cards (1, 2 or
4 channel) from Kvaser (http://www.kvaser.com).
+config CAN_FLEXCAN
+ tristate "Support for Freescale FLEXCAN based chips"
+ depends on CAN_DEV
+ ---help---
+ Say Y here if you want to support for Freescale FlexCAN.
+
config CAN_DEBUG_DEVICES
bool "CAN devices debugging messages"
depends on CAN
diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
index 523a941..25f2032 100644
--- a/drivers/net/can/Makefile
+++ b/drivers/net/can/Makefile
@@ -8,5 +8,6 @@ obj-$(CONFIG_CAN_DEV) += can-dev.o
can-dev-y := dev.o
obj-$(CONFIG_CAN_SJA1000) += sja1000/
+obj-$(CONFIG_CAN_FLEXCAN) += flexcan.o
ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
new file mode 100644
index 0000000..77661b3
--- /dev/null
+++ b/drivers/net/can/flexcan.c
@@ -0,0 +1,719 @@
+/*
+ * flexcan.c - FLEXCAN CAN controller driver
+ *
+ * Copyright (c) 2005-2006 Varma Electronics Oy
+ * Copyright (c) 2009 Sascha Hauer, Pengutronix
+ *
+ * Based on code originally by Andrey Volkov <avolkov@varma-el.com>
+ *
+ * LICENCE:
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/can/netlink.h>
+#include <linux/can/error.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/if_ether.h>
+#include <linux/can/dev.h>
+#include <linux/if_arp.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/list.h>
+#include <linux/can.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#define DRIVER_NAME "flexcan"
+
+/* FLEXCAN module configuration register (CANMCR) bits */
+#define CANMCR_MDIS (1 << 31)
+#define CANMCR_FRZ (1 << 30)
+#define CANMCR_FEN (1 << 29)
+#define CANMCR_HALT (1 << 28)
+#define CANMCR_SOFTRST (1 << 25)
+#define CANMCR_FRZACK (1 << 24)
+#define CANMCR_SUPV (1 << 23)
+#define CANMCR_SRX_DIS (1 << 17)
+#define CANMCR_MAXMB(x) ((x) & 0x0f)
+#define CANMCR_IDAM_A (0 << 8)
+#define CANMCR_IDAM_B (1 << 8)
+#define CANMCR_IDAM_C (2 << 8)
+
+/* FLEXCAN control register (CANCTRL) bits */
+#define CANCTRL_PRESDIV(x) (((x) & 0xff) << 24)
+#define CANCTRL_RJW(x) (((x) & 0x03) << 22)
+#define CANCTRL_PSEG1(x) (((x) & 0x07) << 19)
+#define CANCTRL_PSEG2(x) (((x) & 0x07) << 16)
+#define CANCTRL_BOFFMSK (1 << 15)
+#define CANCTRL_ERRMSK (1 << 14)
+#define CANCTRL_CLKSRC (1 << 13)
+#define CANCTRL_LPB (1 << 12)
+#define CANCTRL_TWRN_MSK (1 << 11)
+#define CANCTRL_RWRN_MSK (1 << 10)
+#define CANCTRL_SAMP (1 << 7)
+#define CANCTRL_BOFFREC (1 << 6)
+#define CANCTRL_TSYNC (1 << 5)
+#define CANCTRL_LBUF (1 << 4)
+#define CANCTRL_LOM (1 << 3)
+#define CANCTRL_PROPSEG(x) ((x) & 0x07)
+
+/* FLEXCAN error counter register (ERRCNT) bits */
+#define ERRCNT_REXECTR(x) (((x) & 0xff) << 8)
+#define ERRCNT_TXECTR(x) ((x) & 0xff)
+
+/* FLEXCAN error and status register (ERRSTAT) bits */
+#define ERRSTAT_TWRNINT (1 << 17)
+#define ERRSTAT_RWRNINT (1 << 16)
+#define ERRSTAT_BIT1ERR (1 << 15)
+#define ERRSTAT_BIT0ERR (1 << 14)
+#define ERRSTAT_ACKERR (1 << 13)
+#define ERRSTAT_CRCERR (1 << 12)
+#define ERRSTAT_FRMERR (1 << 11)
+#define ERRSTAT_STFERR (1 << 10)
+#define ERRSTAT_TXWRN (1 << 9)
+#define ERRSTAT_RXWRN (1 << 8)
+#define ERRSTAT_IDLE (1 << 7)
+#define ERRSTAT_TXRX (1 << 6)
+#define ERRSTAT_FLTCONF_MASK (3 << 4)
+#define ERRSTAT_FLTCONF_ERROR_ACTIVE (0 << 4)
+#define ERRSTAT_FLTCONF_ERROR_PASSIVE (1 << 4)
+#define ERRSTAT_FLTCONF_ERROR_BUS_OFF (2 << 4)
+#define ERRSTAT_BOFFINT (1 << 2)
+#define ERRSTAT_ERRINT (1 << 1)
+#define ERRSTAT_WAKINT (1 << 0)
+#define ERRSTAT_INT (ERRSTAT_BOFFINT | ERRSTAT_ERRINT | ERRSTAT_TWRNINT | \
+ ERRSTAT_RWRNINT)
+
+/* FLEXCAN interrupt flag register (IFLAG) bits */
+#define IFLAG_BUF(x) (1 << (x))
+#define IFLAG_RX_FIFO_OVERFLOW (1 << 7)
+#define IFLAG_RX_FIFO_WARN (1 << 6)
+#define IFLAG_RX_FIFO_AVAILABLE (1 << 5)
+
+/* FLEXCAN message buffers */
+#define MB_CNT_CODE(x) (((x) & 0xf) << 24)
+#define MB_CNT_SRR (1 << 22)
+#define MB_CNT_IDE (1 << 21)
+#define MB_CNT_RTR (1 << 20)
+#define MB_CNT_LENGTH(x) (((x) & 0xf) << 16)
+#define MB_CNT_TIMESTAMP(x) ((x) & 0xffff)
+
+#define MB_ID_STD (0x7ff << 18)
+#define MB_ID_EXT 0x1fffffff
+#define MB_CODE_MASK 0xf0ffffff
+
+/* Structure of the message buffer */
+struct flexcan_mb {
+ u32 can_ctrl;
+ u32 can_id;
+ u32 data[2];
+};
+
+/* Structure of the hardware registers */
+struct flexcan_regs {
+ u32 canmcr; /* 0x00 */
+ u32 canctrl; /* 0x04 */
+ u32 timer; /* 0x08 */
+ u32 reserved1; /* 0x0c */
+ u32 rxgmask; /* 0x10 */
+ u32 rx14mask; /* 0x14 */
+ u32 rx15mask; /* 0x18 */
+ u32 errcnt; /* 0x1c */
+ u32 errstat; /* 0x20 */
+ u32 imask2; /* 0x24 */
+ u32 imask1; /* 0x28 */
+ u32 iflag2; /* 0x2c */
+ u32 iflag1; /* 0x30 */
+ u32 reserved4[19];
+ struct flexcan_mb cantxfg[64];
+};
+
+struct flexcan_priv {
+ struct can_priv can;
+ void __iomem *base;
+
+ struct net_device *dev;
+ struct clk *clk;
+};
+
+static struct can_bittiming_const flexcan_bittiming_const = {
+ .name = DRIVER_NAME,
+ .tseg1_min = 1,
+ .tseg1_max = 16,
+ .tseg2_min = 2,
+ .tseg2_max = 8,
+ .sjw_max = 4,
+ .brp_min = 1,
+ .brp_max = 256,
+ .brp_inc = 1,
+};
+
+#define TX_BUF_ID 8
+
+static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct can_frame *frame = (struct can_frame *)skb->data;
+ struct flexcan_priv *priv = netdev_priv(dev);
+ struct flexcan_regs __iomem *regs = priv->base;
+ u32 can_id;
+ u32 ctrl = MB_CNT_CODE(0xc) | (frame->can_dlc << 16);
+
+ netif_stop_queue(dev);
+
+ if (frame->can_id & CAN_EFF_FLAG) {
+ can_id = frame->can_id & CAN_EFF_MASK;
+ ctrl |= MB_CNT_IDE | MB_CNT_SRR;
+ } else {
+ can_id = (frame->can_id & CAN_SFF_MASK) << 18;
+ }
+
+ if (frame->can_id & CAN_RTR_FLAG)
+ ctrl |= MB_CNT_RTR;
+
+ if (frame->can_dlc > 0) {
+ u32 data;
+ data = frame->data[0] << 24;
+ data |= frame->data[1] << 16;
+ data |= frame->data[2] << 8;
+ data |= frame->data[3];
+ writel(data, ®s->cantxfg[TX_BUF_ID].data[0]);
+ }
+ if (frame->can_dlc > 3) {
+ u32 data;
+ data = frame->data[4] << 24;
+ data |= frame->data[5] << 16;
+ data |= frame->data[6] << 8;
+ data |= frame->data[7];
+ writel(data, ®s->cantxfg[TX_BUF_ID].data[1]);
+ }
+
+ writel(can_id, ®s->cantxfg[TX_BUF_ID].can_id);
+ writel(ctrl, ®s->cantxfg[TX_BUF_ID].can_ctrl);
+
+ kfree_skb(skb);
+
+ return NETDEV_TX_OK;
+}
+
+static void flexcan_rx_frame(struct net_device *ndev,
+ struct flexcan_mb __iomem *mb)
+{
+ struct net_device_stats *stats = &ndev->stats;
+ struct sk_buff *skb;
+ struct can_frame *frame;
+ int ctrl, length;
+ u32 id;
+
+ ctrl = readl(&mb->can_ctrl);
+ length = (ctrl >> 16) & 0x0f;
+ if (length > 8) {
+ stats->rx_dropped++;
+ return;
+ }
+
+ skb = dev_alloc_skb(sizeof(struct can_frame));
+ if (!skb) {
+ stats->rx_dropped++;
+ return;
+ }
+
+ frame = (struct can_frame *)skb_put(skb,
+ sizeof(struct can_frame));
+
+ frame->can_dlc = length;
+ id = readl(&mb->can_id);
+
+ if (ctrl & MB_CNT_IDE) {
+ frame->can_id = id & CAN_EFF_MASK;
+ frame->can_id |= CAN_EFF_FLAG;
+ } else {
+ frame->can_id = (id >> 18) & CAN_SFF_MASK;
+ }
+
+ if (ctrl & MB_CNT_RTR)
+ frame->can_id |= CAN_RTR_FLAG;
+
+ if (length > 0) {
+ u32 data = readl(&mb->data[0]);
+ frame->data[0] = (data >> 24) & 0xff;
+ frame->data[1] = (data >> 16) & 0xff;
+ frame->data[2] = (data >> 8) & 0xff;
+ frame->data[3] = data & 0xff;
+ }
+ if (length > 3) {
+ u32 data = readl(&mb->data[1]);
+ frame->data[4] = (data >> 24) & 0xff;
+ frame->data[5] = (data >> 16) & 0xff;
+ frame->data[6] = (data >> 8) & 0xff;
+ frame->data[7] = data & 0xff;
+ }
+
+ stats->rx_packets++;
+ stats->rx_bytes += frame->can_dlc;
+ skb->dev = ndev;
+ skb->protocol = __constant_htons(ETH_P_CAN);
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+ netif_rx(skb);
+}
+
+static void flexcan_error(struct net_device *ndev, u32 stat)
+{
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ struct flexcan_priv *priv = netdev_priv(ndev);
+ struct net_device_stats *stats = &ndev->stats;
+ enum can_state state = priv->can.state;
+ int error_warning = 0, rx_errors = 0, tx_errors = 0;
+
+ skb = dev_alloc_skb(sizeof(struct can_frame));
+ if (!skb)
+ return;
+
+ skb->dev = ndev;
+ skb->protocol = __constant_htons(ETH_P_CAN);
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+ cf = (struct can_frame *)skb_put(skb, sizeof(*cf));
+ memset(cf, 0, sizeof(*cf));
+
+ cf->can_id = CAN_ERR_FLAG;
+ cf->can_dlc = CAN_ERR_DLC;
+
+ if (stat & ERRSTAT_RWRNINT) {
+ error_warning = 1;
+ cf->data[1] |= CAN_ERR_CRTL_RX_WARNING;
+ }
+
+ if (stat & ERRSTAT_TWRNINT) {
+ error_warning = 1;
+ cf->data[1] |= CAN_ERR_CRTL_TX_WARNING;
+ }
+
+ switch ((stat >> 4) & 0x3) {
+ case 0:
+ state = CAN_STATE_ERROR_ACTIVE;
+ break;
+ case 1:
+ state = CAN_STATE_ERROR_PASSIVE;
+ break;
+ default:
+ state = CAN_STATE_BUS_OFF;
+ break;
+ }
+
+ if (stat & ERRSTAT_BOFFINT) {
+ cf->can_id |= CAN_ERR_BUSOFF;
+ can_bus_off(ndev);
+ }
+
+ if (stat & ERRSTAT_BIT1ERR) {
+ rx_errors = 1;
+ cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+ cf->data[2] |= CAN_ERR_PROT_BIT1;
+ }
+
+ if (stat & ERRSTAT_BIT0ERR) {
+ rx_errors = 1;
+ cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+ cf->data[2] |= CAN_ERR_PROT_BIT0;
+ }
+
+ if (stat & ERRSTAT_FRMERR) {
+ rx_errors = 1;
+ cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+ cf->data[2] |= CAN_ERR_PROT_FORM;
+ }
+
+ if (stat & ERRSTAT_STFERR) {
+ rx_errors = 1;
+ cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+ cf->data[2] |= CAN_ERR_PROT_STUFF;
+ }
+
+
+ if (stat & ERRSTAT_ACKERR) {
+ tx_errors = 1;
+ cf->can_id |= CAN_ERR_ACK;
+ }
+
+ if (error_warning)
+ priv->can.can_stats.error_warning++;
+ if (rx_errors)
+ stats->rx_errors++;
+ if (tx_errors)
+ stats->tx_errors++;
+
+ priv->can.state = state;
+
+ netif_rx(skb);
+
+ ndev->last_rx = jiffies;
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+}
+
+static irqreturn_t flexcan_isr(int irq, void *dev_id)
+{
+ struct net_device *ndev = dev_id;
+ struct net_device_stats *stats = &ndev->stats;
+ struct flexcan_priv *priv = netdev_priv(ndev);
+ struct flexcan_regs __iomem *regs = priv->base;
+ u32 iflags, errstat;
+
+ errstat = readl(®s->errstat);
+ if (errstat & ERRSTAT_INT) {
+ flexcan_error(ndev, errstat);
+ writel(errstat & ERRSTAT_INT, ®s->errstat);
+ }
+
+ iflags = readl(®s->iflag1);
+
+ if (iflags & IFLAG_RX_FIFO_OVERFLOW) {
+ writel(IFLAG_RX_FIFO_OVERFLOW, ®s->iflag1);
+ stats->rx_over_errors++;
+ stats->rx_errors++;
+ }
+
+ while (iflags & IFLAG_RX_FIFO_AVAILABLE) {
+ struct flexcan_mb __iomem *mb = ®s->cantxfg[0];
+
+ flexcan_rx_frame(ndev, mb);
+ writel(IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1);
+ readl(®s->timer);
+ iflags = readl(®s->iflag1);
+ }
+
+ if (iflags & (1 << TX_BUF_ID)) {
+ stats->tx_packets++;
+ writel((1 << TX_BUF_ID), ®s->iflag1);
+ netif_wake_queue(ndev);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int flexcan_set_bittiming(struct net_device *ndev)
+{
+ struct flexcan_priv *priv = netdev_priv(ndev);
+ struct can_bittiming *bt = &priv->can.bittiming;
+ struct flexcan_regs __iomem *regs = priv->base;
+ u32 reg;
+
+ reg = readl(®s->canctrl);
+ reg &= ~(CANCTRL_SAMP | CANCTRL_PRESDIV(0xff) |
+ CANCTRL_PSEG1(7) | CANCTRL_PSEG2(7));
+ reg |= CANCTRL_PRESDIV(bt->brp - 1) |
+ CANCTRL_PSEG1(bt->phase_seg1 - 1) |
+ CANCTRL_PSEG2(bt->phase_seg2 - 1) |
+ CANCTRL_RJW(3) |
+ CANCTRL_PROPSEG(bt->prop_seg - 1);
+ if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
+ reg |= CANCTRL_SAMP;
+ writel(reg, ®s->canctrl);
+
+ dev_dbg(&ndev->dev, "setting canctrl=0x%08x\n", reg);
+
+ return 0;
+}
+
+static int flexcan_open(struct net_device *ndev)
+{
+ int ret, i;
+ struct flexcan_priv *priv = netdev_priv(ndev);
+ struct flexcan_regs __iomem *regs = priv->base;
+ u32 reg;
+
+ ret = open_candev(ndev);
+ if (ret)
+ return ret;
+
+ ret = request_irq(ndev->irq, flexcan_isr, 0, DRIVER_NAME, ndev);
+ if (ret)
+ goto err_irq;
+
+ clk_enable(priv->clk);
+
+ reg = CANMCR_SOFTRST | CANMCR_HALT;
+ writel(CANMCR_SOFTRST, ®s->canmcr);
+ udelay(10);
+
+ if (readl(®s->canmcr) & CANMCR_SOFTRST) {
+ dev_err(&ndev->dev, "Failed to softreset can module.\n");
+ ret = -ENODEV;
+ goto err_reset;
+ }
+
+ /* Enable error and bus off interrupt */
+ reg = readl(®s->canctrl);
+ reg |= CANCTRL_CLKSRC | CANCTRL_ERRMSK | CANCTRL_BOFFMSK |
+ CANCTRL_BOFFREC | CANCTRL_TWRN_MSK | CANCTRL_TWRN_MSK;
+ writel(reg, ®s->canctrl);
+
+ /* Set lowest buffer transmitted first */
+ reg |= CANCTRL_LBUF;
+ writel(reg, ®s->canctrl);
+
+ for (i = 0; i < 64; i++) {
+ writel(0, ®s->cantxfg[i].can_ctrl);
+ writel(0, ®s->cantxfg[i].can_id);
+ writel(0, ®s->cantxfg[i].data[0]);
+ writel(0, ®s->cantxfg[i].data[1]);
+
+ /* Put MB into rx queue */
+ writel(MB_CNT_CODE(0x04), ®s->cantxfg[i].can_ctrl);
+ }
+
+ /* acceptance mask/acceptance code (accept everything) */
+ writel(0x0, ®s->rxgmask);
+ writel(0x0, ®s->rx14mask);
+ writel(0x0, ®s->rx15mask);
+
+ /* Enable flexcan module */
+ reg = readl(®s->canmcr);
+ reg &= ~(CANMCR_MDIS | CANMCR_FRZ);
+ reg |= CANMCR_IDAM_C | CANMCR_FEN;
+ writel(reg, ®s->canmcr);
+
+ /* Synchronize with the can bus */
+ reg &= ~CANMCR_HALT;
+ writel(reg, ®s->canmcr);
+
+ /* Enable interrupts */
+ writel(IFLAG_RX_FIFO_OVERFLOW | IFLAG_RX_FIFO_AVAILABLE |
+ IFLAG_BUF(TX_BUF_ID),
+ ®s->imask1);
+
+ netif_start_queue(ndev);
+
+ return 0;
+
+err_reset:
+ free_irq(ndev->irq, ndev);
+err_irq:
+ close_candev(ndev);
+
+ return ret;
+}
+
+static int flexcan_close(struct net_device *ndev)
+{
+ struct flexcan_priv *priv = netdev_priv(ndev);
+ struct flexcan_regs __iomem *regs = priv->base;
+
+ netif_stop_queue(ndev);
+
+ /* Disable all interrupts */
+ writel(0, ®s->imask1);
+ free_irq(ndev->irq, ndev);
+
+ close_candev(ndev);
+
+ /* Disable module */
+ writel(CANMCR_MDIS, ®s->canmcr);
+ clk_disable(priv->clk);
+ return 0;
+}
+
+static int flexcan_set_mode(struct net_device *ndev, enum can_mode mode)
+{
+ struct flexcan_priv *priv = netdev_priv(ndev);
+ struct flexcan_regs __iomem *regs = priv->base;
+ u32 reg;
+
+ switch (mode) {
+ case CAN_MODE_START:
+ reg = readl(®s->canctrl);
+ reg &= ~CANCTRL_BOFFREC;
+ writel(reg, ®s->canctrl);
+ reg |= CANCTRL_BOFFREC;
+ writel(reg, ®s->canctrl);
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+ if (netif_queue_stopped(ndev))
+ netif_wake_queue(ndev);
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+static const struct net_device_ops flexcan_netdev_ops = {
+ .ndo_open = flexcan_open,
+ .ndo_stop = flexcan_close,
+ .ndo_start_xmit = flexcan_start_xmit,
+};
+
+static int register_flexcandev(struct net_device *ndev)
+{
+ struct flexcan_priv *priv = netdev_priv(ndev);
+ struct flexcan_regs __iomem *regs = priv->base;
+ u32 reg;
+
+ reg = readl(®s->canmcr);
+ reg &= ~CANMCR_MDIS;
+ writel(reg, ®s->canmcr);
+ udelay(100);
+ reg |= CANMCR_FRZ | CANMCR_HALT | CANMCR_FEN;
+ writel(reg, ®s->canmcr);
+
+ reg = readl(®s->canmcr);
+
+ /* Currently we only support newer versions of this core featuring
+ * a RX FIFO. Older cores found on some Coldfire derivates are not
+ * yet supported.
+ */
+ if (!(reg & CANMCR_FEN)) {
+ dev_err(&ndev->dev, "Could not enable RX FIFO, unsupported "
+ "core");
+ return -ENODEV;
+ }
+
+ ndev->flags |= IFF_ECHO; /* we support local echo in hardware */
+ ndev->netdev_ops = &flexcan_netdev_ops;
+
+ return register_candev(ndev);
+}
+
+static void unregister_flexcandev(struct net_device *ndev)
+{
+ struct flexcan_priv *priv = netdev_priv(ndev);
+ struct flexcan_regs __iomem *regs = priv->base;
+ u32 reg;
+
+ reg = readl(®s->canmcr);
+ reg |= CANMCR_FRZ | CANMCR_HALT | CANMCR_MDIS;
+ writel(reg, ®s->canmcr);
+
+ unregister_candev(ndev);
+}
+
+static int __devinit flexcan_probe(struct platform_device *pdev)
+{
+ struct resource *mem;
+ struct net_device *ndev;
+ struct flexcan_priv *priv;
+ u32 mem_size;
+ int ret;
+
+ ndev = alloc_candev(sizeof(struct flexcan_priv));
+ if (!ndev)
+ return -ENOMEM;
+
+ priv = netdev_priv(ndev);
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ ndev->irq = platform_get_irq(pdev, 0);
+ if (!mem || !ndev->irq) {
+ ret = -ENODEV;
+ goto failed_req;
+ }
+
+ mem_size = resource_size(mem);
+
+ if (!request_mem_region(mem->start, mem_size, DRIVER_NAME)) {
+ ret = -EBUSY;
+ goto failed_req;
+ }
+
+ SET_NETDEV_DEV(ndev, &pdev->dev);
+
+ priv->base = ioremap(mem->start, mem_size);
+ if (!priv->base) {
+ ret = -ENOMEM;
+ goto failed_map;
+ }
+
+ priv->clk = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(priv->clk)) {
+ ret = PTR_ERR(priv->clk);
+ goto failed_clock;
+ }
+ priv->can.clock.freq = clk_get_rate(priv->clk);
+
+ platform_set_drvdata(pdev, ndev);
+
+ priv->can.do_set_bittiming = flexcan_set_bittiming;
+ priv->can.bittiming_const = &flexcan_bittiming_const;
+ priv->can.do_set_mode = flexcan_set_mode;
+
+ ret = register_flexcandev(ndev);
+ if (ret)
+ goto failed_register;
+
+ return 0;
+
+failed_register:
+ clk_put(priv->clk);
+failed_clock:
+ iounmap(priv->base);
+failed_map:
+ release_mem_region(mem->start, mem_size);
+failed_req:
+ free_candev(ndev);
+
+ return ret;
+}
+
+static int __devexit flexcan_remove(struct platform_device *pdev)
+{
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct flexcan_priv *priv = netdev_priv(ndev);
+ struct resource *mem;
+
+ unregister_flexcandev(ndev);
+ platform_set_drvdata(pdev, NULL);
+ iounmap(priv->base);
+ clk_put(priv->clk);
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(mem->start, resource_size(mem));
+ free_candev(ndev);
+
+ return 0;
+}
+
+static struct platform_driver flexcan_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ },
+ .probe = flexcan_probe,
+ .remove = __devexit_p(flexcan_remove),
+};
+
+static int __init flexcan_init(void)
+{
+ return platform_driver_register(&flexcan_driver);
+}
+
+static void __exit flexcan_exit(void)
+{
+ platform_driver_unregister(&flexcan_driver);
+}
+
+module_init(flexcan_init);
+module_exit(flexcan_exit);
+
+MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("CAN port driver for flexcan based chip");
--
1.6.3.3
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply related
* Re: [RFC] Idea about increasing efficency of skb allocation in network devices
From: Brice Goglin @ 2009-07-29 8:20 UTC (permalink / raw)
To: Neil Horman; +Cc: Eric Dumazet, David Miller, netdev
In-Reply-To: <20090727105554.GB15823@hmsreliant.think-freely.org>
Neil Horman wrote:
>>> Is there an easy way to get this NUMA node from the application socket
>>> descriptor?
>>>
>> Thats not easy, this information can change for every packet (think of
>> bonding setups, whith aggregation of devices on different NUMA nodes)
>>
>> We could add a getsockopt() call to peek this information from the next
>> data to be read from socket (returns node id where skb data is sitting,
>> hoping that NIC driver hadnt copybreak it (ie : allocate a small skb and
>> copy the device provided data on it before feeding packet to network stack))
>>
>>
> Would a proc or debugfs interface perhaps be helpful here? Something that
> perhaps showed a statistical distribution of how many packets were received by
> each process on each irq (operating under the assumption that each rx queue has
> its own msi irq, giving us an easy identifier).
>
It could be intereting. But unprivileged user processes cannot read
/proc/irq/*/smp_affinity, so they would not be able to translate your
procfs information into a binding hint.
Brice
^ permalink raw reply
* FW: System Hang while trying to send over TCP socket with very less free m/m
From: manu gautam @ 2009-07-29 8:24 UTC (permalink / raw)
To: netdev, LKML
Hi,
I am running 2.6.12 kernel with kernel PREEMPTION being OFF.
While sending data over TCP socket I am experiencing system hang. What is happening actually is that the system is low in free memory and the sk_stream_alloc_pskb call in tcp_sendmsg fails and the control goes to "sk_stream_wait_memory" function. Inside this function we are calling schedule_timeout only if "sk_stream_memory_free(sk) && vm_wait" check is false. In my case what happens is that this check is always true and we don't do schedule_timeout which results in the system hang.
With preemption being OFF it becomes a kind of deadlock where the one thread is waiting for the memory to be freed but it is not getting scheduled out.
I also checked on the latest kernel but there also I dont see any fix for this issue.
Please excuse me if I have pasted it to some wrong mailing list.
Regards,Manu
_________________________________________________________________
Missed any of the IPL matches ? Catch a recap of all the action on MSN Videos
http://msnvideos.in/iplt20/msnvideoplayer.aspx
^ permalink raw reply
* Re: [PATCH] cnic: Fix ISCSI_KEVENT_IF_DOWN message handling.
From: Anil Veerabhadrappa @ 2009-07-29 8:42 UTC (permalink / raw)
To: open-iscsi@googlegroups.com
Cc: 'Mike Christie', davem@davemloft.net,
James.Bottomley@HansenPartnership.com, netdev@vger.kernel.org,
linux-scsi@vger.kernel.org
In-Reply-To: <C27F8246C663564A84BB7AB343977242178EE780E1@IRVEXCHCCR01.corp.ad.broadcom.com>
On Wed, 2009-07-29 at 00:55 -0700, Michael Chan wrote:
> Mike Christie wrote:
>
> > Michael Chan wrote:
> > > When a net device goes down or when the bnx2i driver is unloaded,
> > > the code was not generating the ISCSI_KEVENT_IF_DOWN message
> > > properly and this could cause the userspace driver to crash.
> > >
> > > This is fixed by sending the message properly in the shutdown
> path.
> > > cnic_uio_stop() is also added to send the message when bnx2i is
> > > unregistering.
> > >
> > > Signed-off-by: Michael Chan <mchan@broadcom.com>
> > > ---
> > > drivers/net/cnic.c | 23 +++++++++++++++++++++--
> > > 1 files changed, 21 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
> > > index 4d1515f..4869d77 100644
> > > --- a/drivers/net/cnic.c
> > > +++ b/drivers/net/cnic.c
> > > @@ -227,7 +227,7 @@ static int cnic_send_nlmsg(struct
> > cnic_local *cp, u32 type,
> > > }
> > >
> > > rcu_read_lock();
> > > - ulp_ops = rcu_dereference(cp->ulp_ops[CNIC_ULP_ISCSI]);
> > > + ulp_ops = rcu_dereference(cnic_ulp_tbl[CNIC_ULP_ISCSI]);
> > > if (ulp_ops)
> > > ulp_ops->iscsi_nl_send_msg(cp->dev, msg_type, buf,
> len);
> > > rcu_read_unlock();
> > > @@ -319,6 +319,20 @@ static int cnic_abort_prep(struct
> > cnic_sock *csk)
> > > return 0;
> > > }
> > >
> > > +static void cnic_uio_stop(void)
> > > +{
> > > + struct cnic_dev *dev;
> > > +
> > > + read_lock(&cnic_dev_lock);
> > > + list_for_each_entry(dev, &cnic_dev_list, list) {
> > > + struct cnic_local *cp = dev->cnic_priv;
> > > +
> > > + if (cp->cnic_uinfo)
> > > + cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN,
> NULL);
> >
> > I don't think you can call this with the cnic_dev_lock held.
> > They have
> > the same sleeping restrictions as a spin_lock right? If so,
> > the problem
> > is that iscsi_nl_send_ms calls iscsi_offload_mesg which uses
> GFP_NOIO
> > and can sleep.
> >
> >
> In that case, can I send in a patch to change iscsi_offload_mesg() to
> use GFP_ATOMIC?
>
After this change, if iscsi_transport is unable to push the message to
user daemon because of memory issues, will the original issue of uio
crash re-appear?
Original issue: A did not notify B
Fix : A calls C to send message to B
if C cannot deliver message to B, original problem stays???
>
> --~--~---------~--~----~------------~-------~--~----~
> You received this message because you are subscribed to the Google Groups "open-iscsi" group.
> To post to this group, send email to open-iscsi@googlegroups.com
> To unsubscribe from this group, send email to open-iscsi+unsubscribe@googlegroups.com
> For more options, visit this group at http://groups.google.com/group/open-iscsi
> -~----------~----~----~----~------~----~------~--~---
>
>
^ permalink raw reply
* Re: [PATCH V3] CAN: Add Flexcan CAN controller driver
From: Oliver Hartkopp @ 2009-07-29 8:45 UTC (permalink / raw)
To: Sascha Hauer; +Cc: Linux Netdev List, Socketcan-core
In-Reply-To: <20090729082010.GZ2714@pengutronix.de>
Sascha Hauer wrote:
> And another go...
>
> Sascha
>
>
> From 9f6f6fb67d57d082e056dec8121f1423c1b4fa0b Mon Sep 17 00:00:00 2001
> From: Sascha Hauer <s.hauer@pengutronix.de>
> Date: Tue, 21 Jul 2009 10:47:19 +0200
> Subject: [PATCH] CAN: Add Flexcan CAN driver
>
> This core is found on some Freescale SoCs and also some Coldfire
> SoCs. Support for Coldfire is missing though at the moment as
> they have an older revision of the core which does not have RX FIFO
> support.
>
> V3: integrated comments from Oliver Hartkopp
> V2: integrated comments from Wolfgang Grandegger
>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Thanks Sascha!
The register access and the transition between the struct can_frame became
much clearer now.
Looks good to me.
Best regards,
Oliver
^ permalink raw reply
* Re: [PATCH V3] CAN: Add Flexcan CAN controller driver
From: Wolfgang Grandegger @ 2009-07-29 9:09 UTC (permalink / raw)
To: Sascha Hauer; +Cc: Linux Netdev List, Socketcan-core
In-Reply-To: <20090729082010.GZ2714@pengutronix.de>
Sascha Hauer wrote:
> And another go...
>
> Sascha
>
>
>>From 9f6f6fb67d57d082e056dec8121f1423c1b4fa0b Mon Sep 17 00:00:00 2001
> From: Sascha Hauer <s.hauer@pengutronix.de>
> Date: Tue, 21 Jul 2009 10:47:19 +0200
> Subject: [PATCH] CAN: Add Flexcan CAN driver
>
> This core is found on some Freescale SoCs and also some Coldfire
> SoCs. Support for Coldfire is missing though at the moment as
> they have an older revision of the core which does not have RX FIFO
> support.
>
> V3: integrated comments from Oliver Hartkopp
> V2: integrated comments from Wolfgang Grandegger
>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
> drivers/net/can/Kconfig | 6 +
> drivers/net/can/Makefile | 1 +
> drivers/net/can/flexcan.c | 719 +++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 726 insertions(+), 0 deletions(-)
> create mode 100644 drivers/net/can/flexcan.c
>
> diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
> index 33821a8..99c6da4 100644
> --- a/drivers/net/can/Kconfig
> +++ b/drivers/net/can/Kconfig
> @@ -74,6 +74,12 @@ config CAN_KVASER_PCI
> This driver is for the the PCIcanx and PCIcan cards (1, 2 or
> 4 channel) from Kvaser (http://www.kvaser.com).
>
> +config CAN_FLEXCAN
> + tristate "Support for Freescale FLEXCAN based chips"
> + depends on CAN_DEV
> + ---help---
> + Say Y here if you want to support for Freescale FlexCAN.
> +
> config CAN_DEBUG_DEVICES
> bool "CAN devices debugging messages"
> depends on CAN
> diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
> index 523a941..25f2032 100644
> --- a/drivers/net/can/Makefile
> +++ b/drivers/net/can/Makefile
> @@ -8,5 +8,6 @@ obj-$(CONFIG_CAN_DEV) += can-dev.o
> can-dev-y := dev.o
>
> obj-$(CONFIG_CAN_SJA1000) += sja1000/
> +obj-$(CONFIG_CAN_FLEXCAN) += flexcan.o
>
> ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
> diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
> new file mode 100644
> index 0000000..77661b3
> --- /dev/null
> +++ b/drivers/net/can/flexcan.c
[...]
> +static void flexcan_error(struct net_device *ndev, u32 stat)
> +{
> + struct can_frame *cf;
> + struct sk_buff *skb;
> + struct flexcan_priv *priv = netdev_priv(ndev);
> + struct net_device_stats *stats = &ndev->stats;
> + enum can_state state = priv->can.state;
> + int error_warning = 0, rx_errors = 0, tx_errors = 0;
> +
> + skb = dev_alloc_skb(sizeof(struct can_frame));
> + if (!skb)
> + return;
> +
> + skb->dev = ndev;
> + skb->protocol = __constant_htons(ETH_P_CAN);
> + skb->ip_summed = CHECKSUM_UNNECESSARY;
> +
> + cf = (struct can_frame *)skb_put(skb, sizeof(*cf));
> + memset(cf, 0, sizeof(*cf));
> +
> + cf->can_id = CAN_ERR_FLAG;
> + cf->can_dlc = CAN_ERR_DLC;
> +
> + if (stat & ERRSTAT_RWRNINT) {
> + error_warning = 1;
> + cf->data[1] |= CAN_ERR_CRTL_RX_WARNING;
> + }
> +
> + if (stat & ERRSTAT_TWRNINT) {
> + error_warning = 1;
> + cf->data[1] |= CAN_ERR_CRTL_TX_WARNING;
> + }
What is the meaning of this error warning interrupt? It does *not*
change the state.
> + switch ((stat >> 4) & 0x3) {
> + case 0:
> + state = CAN_STATE_ERROR_ACTIVE;
> + break;
> + case 1:
> + state = CAN_STATE_ERROR_PASSIVE;
> + break;
> + default:
> + state = CAN_STATE_BUS_OFF;
> + break;
> + }
I'm still not happy with the error message generation. If a state change
to error passive happens, it should be signaled to the user. Here my ideas:
if (state != priv->can.state) {
if (state == CAN_STATE_ERROR_WARNING) {
cf->data[1] |= CAN_ERR_CRTL_RX_WARNING;
priv->can.can_stats.error_warning++;
} else if (state == CAN_STATE_ERROR_PASSIVE) {
cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
priv->can.can_stats.error_passive++;
}
It might have missed something, though.
Wolfgang.
^ permalink raw reply
* [PATCH] pppoe: fix /proc/net/pppoe
From: Eric Dumazet @ 2009-07-29 9:43 UTC (permalink / raw)
To: David S. Miller
Cc: Pavel Emelyanov, Igor M Podlesny, Andrew Morton, netdev,
Cyrill Gorcunov
In-Reply-To: <4A6F397D.6010606@gmail.com>
Found this one by pppoe code inspection, but this is an old bug.
Igor, this wont fix your problem, sorry !
[PATCH] pppoe: fix /proc/net/pppoe
If a socket is hashed in last slot of pppoe hash table (PPPOE_HASH_SIZE-1)
we report it many times (up to filling seq buffer)
(Only the last socket of last slot)
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c
index f0031f1..5f20902 100644
--- a/drivers/net/pppoe.c
+++ b/drivers/net/pppoe.c
@@ -1063,6 +1063,7 @@ static void *pppoe_seq_next(struct seq_file *seq, void *v, loff_t *pos)
else {
int hash = hash_item(po->pppoe_pa.sid, po->pppoe_pa.remote);
+ po = NULL;
while (++hash < PPPOE_HASH_SIZE) {
po = pn->hash_table[hash];
if (po)
^ permalink raw reply related
* [net-next 2/4] bnx2x: Self-test kills management traffic
From: Eilon Greenstein @ 2009-07-29 10:20 UTC (permalink / raw)
To: David Miller; +Cc: netdev
Self test used to play with the management FIFO possibly while management was
running...
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
drivers/net/bnx2x_main.c | 9 ++++-----
1 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index 5273988..b47b531 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -9415,10 +9415,9 @@ static int bnx2x_test_registers(struct bnx2x *bp)
{ XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 4, 0x00000001 },
{ XCM_REG_WU_DA_CNT_CMD00, 4, 0x00000003 },
{ XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 4, 0x000000ff },
- { NIG_REG_EGRESS_MNG0_FIFO, 20, 0xffffffff },
{ NIG_REG_LLH0_T_BIT, 4, 0x00000001 },
-/* 20 */ { NIG_REG_EMAC0_IN_EN, 4, 0x00000001 },
- { NIG_REG_BMAC0_IN_EN, 4, 0x00000001 },
+ { NIG_REG_EMAC0_IN_EN, 4, 0x00000001 },
+/* 20 */ { NIG_REG_BMAC0_IN_EN, 4, 0x00000001 },
{ NIG_REG_XCM0_OUT_EN, 4, 0x00000001 },
{ NIG_REG_BRB0_OUT_EN, 4, 0x00000001 },
{ NIG_REG_LLH0_XCM_MASK, 4, 0x00000007 },
@@ -9427,8 +9426,8 @@ static int bnx2x_test_registers(struct bnx2x *bp)
{ NIG_REG_LLH0_DEST_MAC_0_0, 160, 0xffffffff },
{ NIG_REG_LLH0_DEST_IP_0_1, 160, 0xffffffff },
{ NIG_REG_LLH0_IPV4_IPV6_0, 160, 0x00000001 },
-/* 30 */ { NIG_REG_LLH0_DEST_UDP_0, 160, 0x0000ffff },
- { NIG_REG_LLH0_DEST_TCP_0, 160, 0x0000ffff },
+ { NIG_REG_LLH0_DEST_UDP_0, 160, 0x0000ffff },
+/* 30 */ { NIG_REG_LLH0_DEST_TCP_0, 160, 0x0000ffff },
{ NIG_REG_LLH0_VLAN_ID_0, 160, 0x00000fff },
{ NIG_REG_XGXS_SERDES0_MODE_SEL, 4, 0x00000001 },
{ NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0, 4, 0x00000001 },
--
1.5.4.3
^ permalink raw reply related
* [net-next 1/4] bnx2x: Receive traffic that maches management filtering rules
From: Eilon Greenstein @ 2009-07-29 10:20 UTC (permalink / raw)
To: David Miller; +Cc: netdev
Due to lack of configuration, if the BMC configures the chip to pass all
broadcast/multicast traffic to it, the host will not receive it. On top of
fixing it, also make sure that in promiscuous mode, the host will receive the
management traffic as well.
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
drivers/net/bnx2x_main.c | 13 +++++++++++++
drivers/net/bnx2x_reg.h | 5 +++++
2 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index a2de0cd..5273988 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -4831,7 +4831,14 @@ static void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
int mode = bp->rx_mode;
int mask = (1 << BP_L_ID(bp));
int func = BP_FUNC(bp);
+ int port = BP_PORT(bp);
int i;
+ /* All but management unicast packets should pass to the host as well */
+ u32 llh_mask =
+ NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_BRCST |
+ NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_MLCST |
+ NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_VLAN |
+ NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_NO_VLAN;
DP(NETIF_MSG_IFUP, "rx mode %d mask 0x%x\n", mode, mask);
@@ -4855,6 +4862,8 @@ static void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
tstorm_mac_filter.ucast_accept_all = mask;
tstorm_mac_filter.mcast_accept_all = mask;
tstorm_mac_filter.bcast_accept_all = mask;
+ /* pass management unicast packets as well */
+ llh_mask |= NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_UNCST;
break;
default:
@@ -4862,6 +4871,10 @@ static void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
break;
}
+ REG_WR(bp,
+ (port ? NIG_REG_LLH1_BRB1_DRV_MASK : NIG_REG_LLH0_BRB1_DRV_MASK),
+ llh_mask);
+
for (i = 0; i < sizeof(struct tstorm_eth_mac_filter_config)/4; i++) {
REG_WR(bp, BAR_TSTRORM_INTMEM +
TSTORM_MAC_FILTER_CONFIG_OFFSET(func) + i * 4,
diff --git a/drivers/net/bnx2x_reg.h b/drivers/net/bnx2x_reg.h
index d771168..8e9e7a2 100644
--- a/drivers/net/bnx2x_reg.h
+++ b/drivers/net/bnx2x_reg.h
@@ -1616,6 +1616,11 @@
/* [RW 1] Set by the MCP to remember if one or more of the drivers is/are
loaded; 0-prepare; -unprepare */
#define MISC_REG_UNPREPARED 0xa424
+#define NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_BRCST (0x1<<0)
+#define NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_MLCST (0x1<<1)
+#define NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_NO_VLAN (0x1<<4)
+#define NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_UNCST (0x1<<2)
+#define NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_VLAN (0x1<<3)
#define NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT (0x1<<0)
#define NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS (0x1<<9)
#define NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G (0x1<<15)
--
1.5.4.3
^ permalink raw reply related
* [net-next 4/4] bnx2x: Version 1.48.114-1
From: Eilon Greenstein @ 2009-07-29 10:20 UTC (permalink / raw)
To: David Miller; +Cc: netdev
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
drivers/net/bnx2x_main.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index 4245412..2d035d7 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -56,8 +56,8 @@
#include "bnx2x_init_ops.h"
#include "bnx2x_dump.h"
-#define DRV_MODULE_VERSION "1.48.113-1"
-#define DRV_MODULE_RELDATE "2009/07/21"
+#define DRV_MODULE_VERSION "1.48.114-1"
+#define DRV_MODULE_RELDATE "2009/07/29"
#define BNX2X_BC_VER 0x040200
#include <linux/firmware.h>
--
1.5.4.3
^ permalink raw reply related
* [net-next 3/4] bnx2x: WoL only with current MAC address
From: Eilon Greenstein @ 2009-07-29 10:20 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In some cases with 57711E, depending on the functions unload sequence, other
functions MAC address could have been used to wake the system as well. Make sure
to block all but the current function if WoL is required by changing the mode
to single function WoL.
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
drivers/net/bnx2x_main.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index b47b531..4245412 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -7354,17 +7354,17 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
for (i = 0; i < MC_HASH_SIZE; i++)
REG_WR(bp, MC_HASH_OFFSET(bp, i), 0);
+
+ REG_WR(bp, MISC_REG_E1HMF_MODE, 0);
}
if (unload_mode == UNLOAD_NORMAL)
reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS;
- else if (bp->flags & NO_WOL_FLAG) {
+ else if (bp->flags & NO_WOL_FLAG)
reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP;
- if (CHIP_IS_E1H(bp))
- REG_WR(bp, MISC_REG_E1HMF_MODE, 0);
- } else if (bp->wol) {
+ else if (bp->wol) {
u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
u8 *mac_addr = bp->dev->dev_addr;
u32 val;
--
1.5.4.3
^ permalink raw reply related
* Re: [PATCH] net: shrink net_device by #ifdef-ing protocol-specific members
From: Octavian Purdila @ 2009-07-29 10:31 UTC (permalink / raw)
To: David Miller; +Cc: lgrijincu, netdev, eric.dumazet
In-Reply-To: <20090728.102808.228535949.davem@davemloft.net>
On Tuesday 28 July 2009 20:28:08 David Miller wrote:
> From: Octavian Purdila <opurdila@ixiacom.com>
> Date: Tue, 28 Jul 2009 17:43:27 +0300
>
> > On Monday 27 July 2009 18:26:44 David Miller wrote:
> >> This benefits, at best, %0.000000001 of users of the Linux kernel,
> >> because every distribution is going to turn on every single option.
> >
> > Not all Linux users are using regular (desktop/server) distributions.
>
> I didn't say all, I said "nearly all" which for many considerations
> is roughly equivalent.
>
> That %0.0000000001 was meant to represent non-distribution users.
There are many embedded / dedicated devices out there which use a customized
Linux kernel (wireless routers and other network appliances, set-top boxes,
TVs, etc.).
I have no idea about what the actual percent of the Linux users these account
for, but to dismiss it as %0.0000000001 seems like a rush statement to me.
tavi
^ permalink raw reply
* Re: [RFC] Idea about increasing efficency of skb allocation in network devices
From: Neil Horman @ 2009-07-29 10:47 UTC (permalink / raw)
To: Brice Goglin; +Cc: Eric Dumazet, David Miller, netdev
In-Reply-To: <4A700667.5080108@inria.fr>
On Wed, Jul 29, 2009 at 10:20:55AM +0200, Brice Goglin wrote:
> Neil Horman wrote:
> >>> Is there an easy way to get this NUMA node from the application socket
> >>> descriptor?
> >>>
> >> Thats not easy, this information can change for every packet (think of
> >> bonding setups, whith aggregation of devices on different NUMA nodes)
> >>
> >> We could add a getsockopt() call to peek this information from the next
> >> data to be read from socket (returns node id where skb data is sitting,
> >> hoping that NIC driver hadnt copybreak it (ie : allocate a small skb and
> >> copy the device provided data on it before feeding packet to network stack))
> >>
> >>
> > Would a proc or debugfs interface perhaps be helpful here? Something that
> > perhaps showed a statistical distribution of how many packets were received by
> > each process on each irq (operating under the assumption that each rx queue has
> > its own msi irq, giving us an easy identifier).
> >
>
> It could be intereting. But unprivileged user processes cannot read
> /proc/irq/*/smp_affinity, so they would not be able to translate your
> procfs information into a binding hint.
>
I don't think you'd need read access to the irq affinity files. If the above
debugfs/proc information were exported to indicate which numa node or cpu the
allocated skb were local to, that could be used by the process to set its
scheduler affintiy via taskset.
Neil
> Brice
>
>
^ permalink raw reply
* [PATCH] [IPV4]: Buffer overflow
From: Roel Kluin @ 2009-07-29 10:52 UTC (permalink / raw)
To: David S. Miller, netdev, Andrew Morton
If arp_format_neigh_entry() can be called with n->dev->addr_len == 0, then a
write to hbuffer[-1] occurs.
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
---
Found with Parfait, http://research.sun.com/projects/parfait/
It's not clear whether this can happen or not.
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index c29d75d..252336f 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -1304,7 +1304,8 @@ static void arp_format_neigh_entry(struct seq_file *seq,
hbuffer[k++] = hex_asc_lo(n->ha[j]);
hbuffer[k++] = ':';
}
- hbuffer[--k] = 0;
+ if (k != 0)
+ hbuffer[--k] = 0;
#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
}
#endif
^ permalink raw reply related
* Re: [RFC] [PATCH] Don't run __qdisc_run() on a stopped TX queue
From: Jarek Poplawski @ 2009-07-29 11:04 UTC (permalink / raw)
To: Herbert Xu; +Cc: David Miller, krkumar2, netdev
In-Reply-To: <20090729004428.GA765@gondor.apana.org.au>
On Wed, Jul 29, 2009 at 08:44:28AM +0800, Herbert Xu wrote:
> On Tue, Jul 28, 2009 at 12:59:19PM -0700, David Miller wrote:
> >
> > The premise is that there'd be only one. The qdisc lock.
> >
> > If the traffic is distributed, flow wise, the driver XMIT
> > lock would spread due to multiqueue.
>
> Suppose that we have a single large flow going through that has
> filled up the hardware queue and is now backlogged in the qdisc
> with qdisc_run on CPU A. Now some other flow comes along and
> sends a packet on CPU B.
>
> So now CPU A and B will both be processing packets for the first
> flow causing loads of lock contention.
>
> But worse yet, we have introduced packet reordering. So are you
> convinced now :)
How about this: instead of the _RUNNING flag we take tx lock while
holding qdisc lock and release qdisc lock just after (before xmit).
This should prevent reordering, and probably could improve cache use:
CPU B which takes qdisc lock only for enqueuing now, would use it for
dequeuing too, plus if accidentally the next xmit goes to a different
tx queue, it could start before CPU A finishes. Otherwise it would
simply wait for CPU A (without tx lock contention). Of course it
needs testing...
Cheers,
Jarek P.
^ permalink raw reply
* Re: [RFC] [PATCH] Don't run __qdisc_run() on a stopped TX queue
From: Herbert Xu @ 2009-07-29 11:11 UTC (permalink / raw)
To: Jarek Poplawski; +Cc: David Miller, krkumar2, netdev
In-Reply-To: <20090729110436.GA5490@ff.dom.local>
On Wed, Jul 29, 2009 at 11:04:36AM +0000, Jarek Poplawski wrote:
>
> How about this: instead of the _RUNNING flag we take tx lock while
> holding qdisc lock and release qdisc lock just after (before xmit).
> This should prevent reordering, and probably could improve cache use:
> CPU B which takes qdisc lock only for enqueuing now, would use it for
> dequeuing too, plus if accidentally the next xmit goes to a different
> tx queue, it could start before CPU A finishes. Otherwise it would
> simply wait for CPU A (without tx lock contention). Of course it
> needs testing...
Well reordering isn't the only problem, the lock contention brought
upon by two CPUs both trying to transmit the same flow from the
qdisc is just as bad.
Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [PATCH] pxaficp-ir - remove incorrect net_device_ops
From: Alexander Beregalov @ 2009-07-29 11:16 UTC (permalink / raw)
To: Eric Miao
Cc: Marek Vasut, linux-arm-kernel, Russell King - ARM Linux, samuel,
netdev
In-Reply-To: <4A6E69FA.9010903@gmail.com>
2009/7/28 Eric Miao <eric.y.miao@gmail.com>:
> Marek Vasut wrote:
>> Hi!
>>
>> This patch fixes broken pxaficp-ir. The problem was in incorrect
>> net_device_ops being specified which prevented the driver from
>> operating. The symptoms were:
>> - failing ifconfig for IrLAN, resulting in
>> SIOCSIFFLAGS: Cannot assign requested address
>> - irattach working for IrCOMM, but the port stayed disabled
>>
>> Moreover this patch corrects missing sysfs device link.
>>
>> btw. guys, be honest, when did you last tested pxaficp-ir on real hardware? ;-)
>>
>
> Well, this seems to be brought by the net_device_ops change, which seems
> to happen silently without any of us being notified.
>
> OK, netdev and Alex are copied, so that we can look into this issue a bit
> deeper:
>
> 1. it looks to me that SIOCSIFFLAGS actually returned -EADDRNOTAVAIL, which
> is likely caused by eth_validate_addr, the default eth_addr comes with
> irda should be "00:00:00:00:00:00" if not explicitly specified (kzalloc),
> and this should be the problem, solution ? Either give a valid address
> to the irda net_device or remove this 'ndo_validate_addr'. And which is
> a correct fix will impact on the .ndo_set_mac_address
>
> 2. '.ndo_change_mtu' ? It looks to me that Irda device doesn't care too much
> about the MTU, eth_change_mtu is supposed to work just fine and not to
> cause any side effects, and may just benefit later irda device drivers if
> there is a weird device happens to care about MTU
>
> - eric
>
> Marek's original patch in attachment.
>
Sorry about that and thanks.
Then we should fix the rest of irda drivers in the same way.
^ permalink raw reply
* Re: [RFC] [PATCH] Don't run __qdisc_run() on a stopped TX queue
From: Jarek Poplawski @ 2009-07-29 11:26 UTC (permalink / raw)
To: Herbert Xu; +Cc: David Miller, krkumar2, netdev
In-Reply-To: <20090729111134.GA6478@gondor.apana.org.au>
On Wed, Jul 29, 2009 at 07:11:34PM +0800, Herbert Xu wrote:
> On Wed, Jul 29, 2009 at 11:04:36AM +0000, Jarek Poplawski wrote:
> >
> > How about this: instead of the _RUNNING flag we take tx lock while
> > holding qdisc lock and release qdisc lock just after (before xmit).
> > This should prevent reordering, and probably could improve cache use:
> > CPU B which takes qdisc lock only for enqueuing now, would use it for
> > dequeuing too, plus if accidentally the next xmit goes to a different
> > tx queue, it could start before CPU A finishes. Otherwise it would
> > simply wait for CPU A (without tx lock contention). Of course it
> > needs testing...
>
> Well reordering isn't the only problem, the lock contention brought
> upon by two CPUs both trying to transmit the same flow from the
> qdisc is just as bad.
If you mean the tx lock there should be no "real" contention: only
one waiter max. qdisc lock's contention might be higher, but it's
use (during contention) better: enqueue + dequeue together instead
of doing it separately.
Cheers,
Jarek P.
^ permalink raw reply
* Re: [PATCH] eexpress: Read buffer overflow
From: Roel Kluin @ 2009-07-29 12:15 UTC (permalink / raw)
To: David Miller; +Cc: netdev, akpm
In-Reply-To: <20090726.184555.56450167.davem@davemloft.net>
start_code is 69 words, but the code always writes a multiple of 16 words,
so the last 11 words written are outside the array.
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
---
Found with Parfait, http://research.sun.com/projects/parfait/
> You've murdered this code, it's even more obfuscated now than it was
> previously.
Was it really that much worse? I though it was more clean. I did test
it to make sure that the semantics were the same.
> Just add the necessary limit tests, and nothing more, so it's
> possible to actually understand your patch. If it's more than
> a 3 line patch, I'm not even going to review it.
3 lines it is, although scripts/checkpatch.pl doesn't like it.
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
---
Found with Parfait, http://research.sun.com/projects/parfait/
3 lines it is, but scripts/checkpatch.pl doesn't like it.
diff --git a/drivers/net/eexpress.c b/drivers/net/eexpress.c
index 1686dca..7b40014 100644
--- a/drivers/net/eexpress.c
+++ b/drivers/net/eexpress.c
@@ -1474,13 +1474,13 @@ static void eexp_hw_init586(struct net_device *dev)
outw(0x0000, ioaddr + 0x800c);
outw(0x0000, ioaddr + 0x800e);
- for (i = 0; i < (sizeof(start_code)); i+=32) {
+ for (i = 0; i < ARRAY_SIZE(start_code); i+=32) {
int j;
outw(i, ioaddr + SM_PTR);
- for (j = 0; j < 16; j+=2)
+ for (j = 0; j < 16 && (i+j)/2 < ARRAY_SIZE(start_code); j+=2)
outw(start_code[(i+j)/2],
ioaddr+0x4000+j);
- for (j = 0; j < 16; j+=2)
+ for (j = 0; j < 16 && (i+j+16)/2 < ARRAY_SIZE(start_code); j+=2)
outw(start_code[(i+j+16)/2],
ioaddr+0x8000+j);
}
^ permalink raw reply related
* Re: [PATCH] eexpress: Read buffer overflow
From: Jarek Poplawski @ 2009-07-29 12:29 UTC (permalink / raw)
To: Roel Kluin; +Cc: David Miller, netdev, akpm
In-Reply-To: <4A703D65.7010805@gmail.com>
On 29-07-2009 14:15, Roel Kluin wrote:
...
> 3 lines it is, but scripts/checkpatch.pl doesn't like it.
>
> diff --git a/drivers/net/eexpress.c b/drivers/net/eexpress.c
> index 1686dca..7b40014 100644
> --- a/drivers/net/eexpress.c
> +++ b/drivers/net/eexpress.c
> @@ -1474,13 +1474,13 @@ static void eexp_hw_init586(struct net_device *dev)
> outw(0x0000, ioaddr + 0x800c);
> outw(0x0000, ioaddr + 0x800e);
>
> - for (i = 0; i < (sizeof(start_code)); i+=32) {
> + for (i = 0; i < ARRAY_SIZE(start_code); i+=32) {
> int j;
> outw(i, ioaddr + SM_PTR);
> - for (j = 0; j < 16; j+=2)
> + for (j = 0; j < 16 && (i+j)/2 < ARRAY_SIZE(start_code); j+=2)
> outw(start_code[(i+j)/2],
> ioaddr+0x4000+j);
> - for (j = 0; j < 16; j+=2)
> + for (j = 0; j < 16 && (i+j+16)/2 < ARRAY_SIZE(start_code); j+=2)
> outw(start_code[(i+j+16)/2],
> ioaddr+0x8000+j);
> }
Now you seem to make my previous math working :-)
>> (max) i = 64, (max) j = 14, (64+14+16)/2 = 47 < 69, so it seems to copy
>> less than its size?
Jarek P.
^ permalink raw reply
* Re: [RFC] [PATCH] Don't run __qdisc_run() on a stopped TX queue
From: Herbert Xu @ 2009-07-29 12:30 UTC (permalink / raw)
To: Jarek Poplawski; +Cc: David Miller, krkumar2, netdev
In-Reply-To: <20090729112614.GB5490@ff.dom.local>
On Wed, Jul 29, 2009 at 11:26:14AM +0000, Jarek Poplawski wrote:
>
> If you mean the tx lock there should be no "real" contention: only
> one waiter max. qdisc lock's contention might be higher, but it's
> use (during contention) better: enqueue + dequeue together instead
> of doing it separately.
Hmm, you will have contention if they're both transmitting a
single flow which must always go into a single physical queue.
So you'll have two CPUs doing the work of a single CPU, with one
of them always spinning on the TX lock.
Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [RFC] [PATCH] Don't run __qdisc_run() on a stopped TX queue
From: Jarek Poplawski @ 2009-07-29 12:47 UTC (permalink / raw)
To: Herbert Xu; +Cc: David Miller, krkumar2, netdev
In-Reply-To: <20090729123041.GA7440@gondor.apana.org.au>
On Wed, Jul 29, 2009 at 08:30:41PM +0800, Herbert Xu wrote:
> On Wed, Jul 29, 2009 at 11:26:14AM +0000, Jarek Poplawski wrote:
> >
> > If you mean the tx lock there should be no "real" contention: only
> > one waiter max. qdisc lock's contention might be higher, but it's
> > use (during contention) better: enqueue + dequeue together instead
> > of doing it separately.
>
> Hmm, you will have contention if they're both transmitting a
> single flow which must always go into a single physical queue.
>
> So you'll have two CPUs doing the work of a single CPU, with one
> of them always spinning on the TX lock.
Hmm.. I'd call it a little waiting, but OK let's call it contention;-)
When tx is faster than queue operations there could be no contention
at all. I'm not saying I must be right: IMHO it's only worth trying.
Cheers,
Jarek P.
^ permalink raw reply
* Re: [RFC] [PATCH] Don't run __qdisc_run() on a stopped TX queue
From: Krishna Kumar2 @ 2009-07-29 13:08 UTC (permalink / raw)
To: Jarek Poplawski; +Cc: David Miller, Herbert Xu, netdev
In-Reply-To: <20090729124734.GD5490@ff.dom.local>
Hi Jarek,
Jarek Poplawski <jarkao2@gmail.com> wrote on 07/29/2009 06:17:34 PM:
> Re: [RFC] [PATCH] Don't run __qdisc_run() on a stopped TX queue
>
> On Wed, Jul 29, 2009 at 08:30:41PM +0800, Herbert Xu wrote:
> > On Wed, Jul 29, 2009 at 11:26:14AM +0000, Jarek Poplawski wrote:
> > >
> > > If you mean the tx lock there should be no "real" contention: only
> > > one waiter max. qdisc lock's contention might be higher, but it's
> > > use (during contention) better: enqueue + dequeue together instead
> > > of doing it separately.
> >
> > Hmm, you will have contention if they're both transmitting a
> > single flow which must always go into a single physical queue.
> >
> > So you'll have two CPUs doing the work of a single CPU, with one
> > of them always spinning on the TX lock.
>
> Hmm.. I'd call it a little waiting, but OK let's call it contention;-)
> When tx is faster than queue operations there could be no contention
> at all. I'm not saying I must be right: IMHO it's only worth trying.
My expectation is that tx would be much longer than a few lines of
queue operation....
thanks,
- KK
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox