* [PATCH net-next-2.6 v9 13/20] pch_can: Fix bit timing calculation issue
From: Tomoya MORINAGA @ 2010-12-13 6:24 UTC (permalink / raw)
To: wg-5Yr1BZd7O62+XT7JhA+gdA, w.sang-bIcnvbaLZ9MEGnE8C9+IrQ,
chripell-VaTbYqLCNhc, 21cnbao-Re5JQEeQqe8AvxtiuMwx3w,
sameo-VuQAYsv1563Yd54FQh9/CA,
socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TZUIDd8j+nm9g
Cc: andrew.chih.howe.khor-ral2JQCrhuEAvxtiuMwx3w,
qi.wang-ral2JQCrhuEAvxtiuMwx3w,
margie.foster-ral2JQCrhuEAvxtiuMwx3w,
yong.y.wang-ral2JQCrhuEAvxtiuMwx3w,
kok.howg.ewe-ral2JQCrhuEAvxtiuMwx3w,
joel.clark-ral2JQCrhuEAvxtiuMwx3w
In-Reply-To: <1292221467-8039-12-git-send-email-tomoya-linux-ECg8zkTtlr0C6LszWs/t0g@public.gmane.org>
Modify like use calculated value directly passed by CAN core module.
Signed-off-by: Tomoya MORINAGA <tomoya-linux-ECg8zkTtlr0C6LszWs/t0g@public.gmane.org>
Acked-by: Marc Kleine-Budde <mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---
drivers/net/can/pch_can.c | 6 ++----
1 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c
index 3540978..5a6a0df 100644
--- a/drivers/net/can/pch_can.c
+++ b/drivers/net/can/pch_can.c
@@ -786,17 +786,15 @@ static int pch_set_bittiming(struct net_device *ndev)
const struct can_bittiming *bt = &priv->can.bittiming;
u32 canbit;
u32 bepe;
- u32 brp;
/* Setting the CCE bit for accessing the Can Timing register. */
pch_can_bit_set(&priv->regs->cont, PCH_CTRL_CCE);
- brp = (bt->tq) / (1000000000/PCH_CAN_CLK) - 1;
- canbit = brp & PCH_MSK_BITT_BRP;
+ canbit = (bt->brp - 1) & PCH_MSK_BITT_BRP;
canbit |= (bt->sjw - 1) << PCH_BIT_SJW_SHIFT;
canbit |= (bt->phase_seg1 + bt->prop_seg - 1) << PCH_BIT_TSEG1_SHIFT;
canbit |= (bt->phase_seg2 - 1) << PCH_BIT_TSEG2_SHIFT;
- bepe = (brp & PCH_MSK_BRPE_BRPE) >> PCH_BIT_BRPE_BRPE_SHIFT;
+ bepe = ((bt->brp - 1) & PCH_MSK_BRPE_BRPE) >> PCH_BIT_BRPE_BRPE_SHIFT;
iowrite32(canbit, &priv->regs->bitt);
iowrite32(bepe, &priv->regs->brpe);
pch_can_bit_clear(&priv->regs->cont, PCH_CTRL_CCE);
--
1.6.0.6
^ permalink raw reply related
* [PATCH net-next-2.6 v9 14/20] pch_can: Fix miss-setting status issue
From: Tomoya MORINAGA @ 2010-12-13 6:24 UTC (permalink / raw)
To: wg, w.sang, chripell, 21cnbao, sameo, socketcan-core, netdev,
linux-kernel
Cc: qi.wang, yong.y.wang, andrew.chih.howe.khor, joel.clark,
kok.howg.ewe, margie.foster, Tomoya MORINAGA
In-Reply-To: <1292221467-8039-13-git-send-email-tomoya-linux@dsn.okisemi.com>
Modify miss-setting status issue at suspend.
Signed-off-by: Tomoya MORINAGA <tomoya-linux@dsn.okisemi.com>
---
drivers/net/can/pch_can.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c
index 5a6a0df..c500b6d 100644
--- a/drivers/net/can/pch_can.c
+++ b/drivers/net/can/pch_can.c
@@ -1073,7 +1073,7 @@ static int pch_can_suspend(struct pci_dev *pdev, pm_message_t state)
pch_can_set_run_mode(priv, PCH_CAN_STOP);
/* Indicate that we are aboutto/in suspend */
- priv->can.state = CAN_STATE_SLEEPING;
+ priv->can.state = CAN_STATE_STOPPED;
/* Waiting for all transmission to complete. */
while (counter) {
--
1.6.0.6
^ permalink raw reply related
* [PATCH net-next-2.6 v9 15/20] pch_can: Comment optimization
From: Tomoya MORINAGA @ 2010-12-13 6:24 UTC (permalink / raw)
To: wg, w.sang, chripell, 21cnbao, sameo, socketcan-core, netdev,
linux-kernel
Cc: qi.wang, yong.y.wang, andrew.chih.howe.khor, joel.clark,
kok.howg.ewe, margie.foster, Tomoya MORINAGA
In-Reply-To: <1292221467-8039-14-git-send-email-tomoya-linux@dsn.okisemi.com>
Comment optimization
Signed-off-by: Tomoya MORINAGA <tomoya-linux@dsn.okisemi.com>
---
drivers/net/can/pch_can.c | 14 +++++++-------
1 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c
index c500b6d..a1fd3be 100644
--- a/drivers/net/can/pch_can.c
+++ b/drivers/net/can/pch_can.c
@@ -292,7 +292,7 @@ static void pch_can_set_rxtx(struct pch_can_priv *priv, u32 buff_num,
else
ie = PCH_IF_MCONT_RXIE;
- /* Reading the receive buffer data from RAM to Interface1/2 registers */
+ /* Reading the Msg buffer from Message RAM to IF1/2 registers. */
iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[dir].cmask);
pch_can_rw_msg_obj(&priv->regs->ifregs[dir].creq, buff_num);
@@ -854,7 +854,7 @@ static int pch_can_open(struct net_device *ndev)
priv->use_msi = 1;
}
- /* Regsitering the interrupt. */
+ /* Regstering the interrupt. */
retval = request_irq(priv->dev->irq, pch_can_interrupt, IRQF_SHARED,
ndev->name, ndev);
if (retval) {
@@ -954,7 +954,7 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev)
can_put_echo_skb(skb, ndev, tx_obj_no - PCH_RX_OBJ_END - 1);
- /* Updating the size of the data. */
+ /* Set the size of the data. Update if2_mcont */
iowrite32(cf->can_dlc | PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_TXRQXT |
PCH_IF_MCONT_TXIE, &priv->regs->ifregs[1].mcont);
@@ -1061,8 +1061,8 @@ static int pch_can_get_buffer_status(struct pch_can_priv *priv)
static int pch_can_suspend(struct pci_dev *pdev, pm_message_t state)
{
- int i; /* Counter variable. */
- int retval; /* Return value. */
+ int i;
+ int retval;
u32 buf_stat; /* Variable for reading the transmit buffer status. */
int counter = PCH_COUNTER_LIMIT;
@@ -1119,8 +1119,8 @@ static int pch_can_suspend(struct pci_dev *pdev, pm_message_t state)
static int pch_can_resume(struct pci_dev *pdev)
{
- int i; /* Counter variable. */
- int retval; /* Return variable. */
+ int i;
+ int retval;
struct net_device *dev = pci_get_drvdata(pdev);
struct pch_can_priv *priv = netdev_priv(dev);
--
1.6.0.6
^ permalink raw reply related
* [PATCH net-next-2.6 v9 16/20] pch_can: Move MSI processing to probe/remove processing
From: Tomoya MORINAGA @ 2010-12-13 6:24 UTC (permalink / raw)
To: wg-5Yr1BZd7O62+XT7JhA+gdA, w.sang-bIcnvbaLZ9MEGnE8C9+IrQ,
chripell-VaTbYqLCNhc, 21cnbao-Re5JQEeQqe8AvxtiuMwx3w,
sameo-VuQAYsv1563Yd54FQh9/CA,
socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TZUIDd8j+nm9g
Cc: andrew.chih.howe.khor-ral2JQCrhuEAvxtiuMwx3w,
qi.wang-ral2JQCrhuEAvxtiuMwx3w,
margie.foster-ral2JQCrhuEAvxtiuMwx3w,
yong.y.wang-ral2JQCrhuEAvxtiuMwx3w,
kok.howg.ewe-ral2JQCrhuEAvxtiuMwx3w,
joel.clark-ral2JQCrhuEAvxtiuMwx3w
In-Reply-To: <1292221467-8039-15-git-send-email-tomoya-linux-ECg8zkTtlr0C6LszWs/t0g@public.gmane.org>
Currently, in case this driver is integrated as module, and when this
module is re-installed, no interrupts is to be occurred.
For the above issue, move MSI processing to open/release processing.
Signed-off-by: Tomoya MORINAGA <tomoya-linux-ECg8zkTtlr0C6LszWs/t0g@public.gmane.org>
---
drivers/net/can/pch_can.c | 29 ++++++++++++++---------------
1 files changed, 14 insertions(+), 15 deletions(-)
diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c
index a1fd3be..ace1fe7 100644
--- a/drivers/net/can/pch_can.c
+++ b/drivers/net/can/pch_can.c
@@ -845,15 +845,6 @@ static int pch_can_open(struct net_device *ndev)
struct pch_can_priv *priv = netdev_priv(ndev);
int retval;
- retval = pci_enable_msi(priv->dev);
- if (retval) {
- netdev_err(ndev, "PCH CAN opened without MSI\n");
- priv->use_msi = 0;
- } else {
- netdev_err(ndev, "PCH CAN opened with MSI\n");
- priv->use_msi = 1;
- }
-
/* Regstering the interrupt. */
retval = request_irq(priv->dev->irq, pch_can_interrupt, IRQF_SHARED,
ndev->name, ndev);
@@ -879,9 +870,6 @@ static int pch_can_open(struct net_device *ndev)
err_open_candev:
free_irq(priv->dev->irq, ndev);
req_irq_err:
- if (priv->use_msi)
- pci_disable_msi(priv->dev);
-
pch_can_release(priv);
return retval;
@@ -895,8 +883,6 @@ static int pch_close(struct net_device *ndev)
napi_disable(&priv->napi);
pch_can_release(priv);
free_irq(priv->dev->irq, ndev);
- if (priv->use_msi)
- pci_disable_msi(priv->dev);
close_candev(ndev);
priv->can.state = CAN_STATE_STOPPED;
return 0;
@@ -975,12 +961,14 @@ static void __devexit pch_can_remove(struct pci_dev *pdev)
struct pch_can_priv *priv = netdev_priv(ndev);
unregister_candev(priv->ndev);
- free_candev(priv->ndev);
pci_iounmap(pdev, priv->regs);
+ if (priv->use_msi)
+ pci_disable_msi(priv->dev);
pci_release_regions(pdev);
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
pch_can_reset(priv);
+ free_candev(priv->ndev);
}
#ifdef CONFIG_PM
@@ -1244,6 +1232,15 @@ static int __devinit pch_can_probe(struct pci_dev *pdev,
netif_napi_add(ndev, &priv->napi, pch_can_poll, PCH_RX_OBJ_END);
+ rc = pci_enable_msi(priv->dev);
+ if (rc) {
+ netdev_err(ndev, "PCH CAN opened without MSI\n");
+ priv->use_msi = 0;
+ } else {
+ netdev_err(ndev, "PCH CAN opened with MSI\n");
+ priv->use_msi = 1;
+ }
+
rc = register_candev(ndev);
if (rc) {
dev_err(&pdev->dev, "Failed register_candev %d\n", rc);
@@ -1253,6 +1250,8 @@ static int __devinit pch_can_probe(struct pci_dev *pdev,
return 0;
probe_exit_reg_candev:
+ if (priv->use_msi)
+ pci_disable_msi(priv->dev);
free_candev(ndev);
probe_exit_alloc_candev:
pci_iounmap(pdev, addr);
--
1.6.0.6
^ permalink raw reply related
* [PATCH net-next-2.6 v9 17/20] pch_can: Fix incorrect return processing
From: Tomoya MORINAGA @ 2010-12-13 6:24 UTC (permalink / raw)
To: wg-5Yr1BZd7O62+XT7JhA+gdA, w.sang-bIcnvbaLZ9MEGnE8C9+IrQ,
chripell-VaTbYqLCNhc, 21cnbao-Re5JQEeQqe8AvxtiuMwx3w,
sameo-VuQAYsv1563Yd54FQh9/CA,
socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TZUIDd8j+nm9g
Cc: andrew.chih.howe.khor-ral2JQCrhuEAvxtiuMwx3w,
qi.wang-ral2JQCrhuEAvxtiuMwx3w,
margie.foster-ral2JQCrhuEAvxtiuMwx3w,
yong.y.wang-ral2JQCrhuEAvxtiuMwx3w,
kok.howg.ewe-ral2JQCrhuEAvxtiuMwx3w,
joel.clark-ral2JQCrhuEAvxtiuMwx3w
In-Reply-To: <1292221467-8039-16-git-send-email-tomoya-linux-ECg8zkTtlr0C6LszWs/t0g@public.gmane.org>
Fix incorrect return processing.
Signed-off-by: Tomoya MORINAGA <tomoya-linux-ECg8zkTtlr0C6LszWs/t0g@public.gmane.org>
---
drivers/net/can/pch_can.c | 19 ++++++++++---------
1 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c
index ace1fe7..8efbe35 100644
--- a/drivers/net/can/pch_can.c
+++ b/drivers/net/can/pch_can.c
@@ -580,9 +580,11 @@ static irqreturn_t pch_can_interrupt(int irq, void *dev_id)
struct net_device *ndev = (struct net_device *)dev_id;
struct pch_can_priv *priv = netdev_priv(ndev);
+ if (!pch_can_int_pending(priv))
+ return IRQ_NONE;
+
pch_can_set_int_enables(priv, PCH_CAN_NONE);
napi_schedule(&priv->napi);
-
return IRQ_HANDLED;
}
@@ -671,8 +673,10 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 obj_num, int quota)
}
skb = alloc_can_skb(priv->ndev, &cf);
- if (!skb)
- return -ENOMEM;
+ if (!skb) {
+ netdev_err(ndev, "alloc_can_skb Failed\n");
+ return rcv_pkts;
+ }
/* Get Received data */
id2 = ioread32(&priv->regs->ifregs[0].id2);
@@ -733,8 +737,8 @@ static int pch_can_poll(struct napi_struct *napi, int quota)
struct net_device *ndev = napi->dev;
struct pch_can_priv *priv = netdev_priv(ndev);
u32 int_stat;
- int rcv_pkts = 0;
u32 reg_stat;
+ int quota_save = quota;
int_stat = pch_can_int_pending(priv);
if (!int_stat)
@@ -763,10 +767,7 @@ static int pch_can_poll(struct napi_struct *napi, int quota)
goto end;
if ((int_stat >= PCH_RX_OBJ_START) && (int_stat <= PCH_RX_OBJ_END)) {
- rcv_pkts += pch_can_rx_normal(ndev, int_stat, quota);
- quota -= rcv_pkts;
- if (quota < 0)
- goto end;
+ quota -= pch_can_rx_normal(ndev, int_stat, quota);
} else if ((int_stat >= PCH_TX_OBJ_START) &&
(int_stat <= PCH_TX_OBJ_END)) {
/* Handle transmission interrupt */
@@ -777,7 +778,7 @@ end:
napi_complete(napi);
pch_can_set_int_enables(priv, PCH_CAN_ALL);
- return rcv_pkts;
+ return quota_save - quota;
}
static int pch_set_bittiming(struct net_device *ndev)
--
1.6.0.6
^ permalink raw reply related
* [PATCH net-next-2.6 v9 18/20] pch_can: Optimize "if" condition in rx/tx processing
From: Tomoya MORINAGA @ 2010-12-13 6:24 UTC (permalink / raw)
To: wg, w.sang, chripell, 21cnbao, sameo, socketcan-core, netdev,
linux-kernel
Cc: qi.wang, yong.y.wang, andrew.chih.howe.khor, joel.clark,
kok.howg.ewe, margie.foster, Tomoya MORINAGA
In-Reply-To: <1292221467-8039-17-git-send-email-tomoya-linux@dsn.okisemi.com>
For reduce "if" condition, easy to read/understand the code,
optimize "if" condition in rx/tx processing.
Signed-off-by: Tomoya MORINAGA <tomoya-linux@dsn.okisemi.com>
Acked-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/pch_can.c | 26 ++++++++++----------------
1 files changed, 10 insertions(+), 16 deletions(-)
diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c
index 8efbe35..dcd8f00 100644
--- a/drivers/net/can/pch_can.c
+++ b/drivers/net/can/pch_can.c
@@ -746,19 +746,16 @@ static int pch_can_poll(struct napi_struct *napi, int quota)
if (int_stat == PCH_STATUS_INT) {
reg_stat = ioread32(&priv->regs->stat);
- if (reg_stat & (PCH_BUS_OFF | PCH_LEC_ALL)) {
- if (reg_stat & PCH_BUS_OFF ||
- (reg_stat & PCH_LEC_ALL) != PCH_LEC_ALL) {
- pch_can_error(ndev, reg_stat);
- quota--;
- }
- }
- if (reg_stat & PCH_TX_OK)
- pch_can_bit_clear(&priv->regs->stat, PCH_TX_OK);
+ if ((reg_stat & (PCH_BUS_OFF | PCH_LEC_ALL)) &&
+ ((reg_stat & PCH_LEC_ALL) != PCH_LEC_ALL)) {
+ pch_can_error(ndev, reg_stat);
+ quota--;
+ }
- if (reg_stat & PCH_RX_OK)
- pch_can_bit_clear(&priv->regs->stat, PCH_RX_OK);
+ if (reg_stat & (PCH_TX_OK | PCH_RX_OK))
+ pch_can_bit_clear(&priv->regs->stat,
+ reg_stat & (PCH_TX_OK | PCH_RX_OK));
int_stat = pch_can_int_pending(priv);
}
@@ -900,14 +897,13 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev)
if (can_dropped_invalid_skb(ndev, skb))
return NETDEV_TX_OK;
+ tx_obj_no = priv->tx_obj;
if (priv->tx_obj == PCH_TX_OBJ_END) {
if (ioread32(&priv->regs->treq2) & PCH_TREQ2_TX_MASK)
netif_stop_queue(ndev);
- tx_obj_no = priv->tx_obj;
priv->tx_obj = PCH_TX_OBJ_START;
} else {
- tx_obj_no = priv->tx_obj;
priv->tx_obj++;
}
@@ -926,9 +922,7 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev)
id2 |= PCH_ID_MSGVAL;
/* If remote frame has to be transmitted.. */
- if (cf->can_id & CAN_RTR_FLAG)
- id2 &= ~PCH_ID2_DIR;
- else
+ if (!(cf->can_id & CAN_RTR_FLAG))
id2 |= PCH_ID2_DIR;
iowrite32(id2, &priv->regs->ifregs[1].id2);
--
1.6.0.6
^ permalink raw reply related
* [PATCH net-next-2.6 v9 19/20] pch_can: Add setting TEC/REC statistics processing
From: Tomoya MORINAGA @ 2010-12-13 6:24 UTC (permalink / raw)
To: wg, w.sang, chripell, 21cnbao, sameo, socketcan-core, netdev,
linux-kernel
Cc: qi.wang, yong.y.wang, andrew.chih.howe.khor, joel.clark,
kok.howg.ewe, margie.foster, Tomoya MORINAGA
In-Reply-To: <1292221467-8039-18-git-send-email-tomoya-linux@dsn.okisemi.com>
Add setting TEC/REC statistics processing.
Signed-off-by: Tomoya MORINAGA <tomoya-linux@dsn.okisemi.com>
---
drivers/net/can/pch_can.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c
index dcd8f00..4697b1c 100644
--- a/drivers/net/can/pch_can.c
+++ b/drivers/net/can/pch_can.c
@@ -568,6 +568,9 @@ static void pch_can_error(struct net_device *ndev, u32 status)
break;
}
+ cf->data[6] = errc & PCH_TEC;
+ cf->data[7] = (errc & PCH_REC) >> 8;
+
priv->can.state = state;
netif_rx(skb);
--
1.6.0.6
^ permalink raw reply related
* Re: [PATCH v2 3/4] kthread: NUMA aware kthread_create_on_cpu()
From: Thomas Fjellstrom @ 2010-12-13 6:26 UTC (permalink / raw)
To: Andrew Morton
Cc: Eric Dumazet, Andi Kleen, linux-kernel, netdev, David Miller,
Tejun Heo, Rusty Russell, Tony Luck, Fenghua Yu
In-Reply-To: <20101209230937.073fab54.akpm@linux-foundation.org>
On December 10, 2010, Andrew Morton wrote:
> On Fri, 10 Dec 2010 08:02:41 +0100 Eric Dumazet <eric.dumazet@gmail.com>
wrote:
> > Le jeudi 09 d__cembre 2010 __ 22:32 -0800, Andrew Morton a __crit :
> > > but but but. The name "kthread_create_on_cpu" sucks. It's plain
> > > wrong.
> >
> > Okay you are right Andrew ;) I dont have better idea for the moment.
>
> Dunno. kthread_create_with_memory_on_node() :)
>
> How's about kthread_create_for_node()? That's sufficiently vague to
> not mislead readers into thinking that it schedules the thread on that
> CPU and leaves room in the namespace for a real kthread_create_on_cpu()
> (which we could well end up creating).
>
> kthread_create_node_mem()?
Just a kernel newb here, how about kthread_create_from_cpu ? unless that has
some connotations I'm not aware of.
> > Note that all callers I converted really create one kthread per cpu, not
> > per node. They didnt care of node affinity, only me :)
> >
> > kthread_create_on_node() seems misleading to me (some cpus run on
> > memoryless nodes)
>
> True, but what we're doing here is specifying on which node the
> kthread's memory resources should reside - we need to do that even for
> CPUs which live on memoryless nodes.
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
--
Thomas Fjellstrom
thomas@fjellstrom.ca
^ permalink raw reply
* Using net_devices with ATM/DSL
From: Philip Prindeville @ 2010-12-13 6:53 UTC (permalink / raw)
To: netdev
I was trying to get this discussion rolling on linux-atm-general but didn't have much luck.
I was wondering what the downside to having ATM/DSL interfaces use net_devices would be?
Part of the reason for wanting to do this is to have an end-point to send/receive netlink messages to, so that the interface can report carrier state transitions, bit rates, bit-error rates, SNR, attenuation, constellations, transmitter gain, etc.
Seems simple enough.
Why not do this?
Thanks,
-Philip
^ permalink raw reply
* use struct sock->sk_protinfo store private data?
From: Rui @ 2010-12-13 7:32 UTC (permalink / raw)
To: netdev
hi
I saw one in-house kernel module use struct sock->sk_protinfo to store
a private data
is it safe? will other parts use it?
quoted from net/sock.h
* @sk_protinfo: private area, net family specific, when not using slab
thanks
rui
^ permalink raw reply
* [PATCH net-next-2.6] tcp: clean up twisted goto in tcp_rcv_synsent_state_process()
From: Yoichi Yuasa @ 2010-12-13 8:11 UTC (permalink / raw)
To: David S. Miller; +Cc: yuasa, netdev
Signed-off-by: Yoichi Yuasa <yuasa@linux-mips.org>
---
net/ipv4/tcp_input.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 824e8c8..ae4200c 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -5623,9 +5623,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
TCP_DELACK_MAX, TCP_RTO_MAX);
-discard:
- __kfree_skb(skb);
- return 0;
+ goto discard;
} else {
tcp_send_ack(sk);
}
@@ -5704,7 +5702,9 @@ discard:
discard_and_undo:
tcp_clear_options(&tp->rx_opt);
tp->rx_opt.mss_clamp = saved_clamp;
- goto discard;
+discard:
+ __kfree_skb(skb);
+ return 0;
reset_and_undo:
tcp_clear_options(&tp->rx_opt);
--
1.7.3.3
^ permalink raw reply related
* [PATCH net-next-2.6 1/2] cpmac: remove unused buflen
From: Yoichi Yuasa @ 2010-12-13 8:17 UTC (permalink / raw)
To: David S. Miller; +Cc: yuasa, netdev, Eugene Konev
Signed-off-by: Yoichi Yuasa <yuasa@linux-mips.org>
---
drivers/net/cpmac.c | 4 ----
1 files changed, 0 insertions(+), 4 deletions(-)
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c
index fec939f..8021756 100644
--- a/drivers/net/cpmac.c
+++ b/drivers/net/cpmac.c
@@ -179,7 +179,6 @@ MODULE_PARM_DESC(dumb_switch, "Assume switch is not connected to MDIO bus");
struct cpmac_desc {
u32 hw_next;
u32 hw_data;
- u16 buflen;
u16 bufflags;
u16 datalen;
u16 dataflags;
@@ -415,7 +414,6 @@ static struct sk_buff *cpmac_rx_one(struct cpmac_priv *priv,
priv->dev->stats.rx_dropped++;
}
- desc->buflen = CPMAC_SKB_SIZE;
desc->dataflags = CPMAC_OWN;
return result;
@@ -586,7 +584,6 @@ static int cpmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
DMA_TO_DEVICE);
desc->hw_data = (u32)desc->data_mapping;
desc->datalen = len;
- desc->buflen = len;
if (unlikely(netif_msg_tx_queued(priv)))
printk(KERN_DEBUG "%s: sending 0x%p, len=%d\n", dev->name, skb,
skb->len);
@@ -1005,7 +1002,6 @@ static int cpmac_open(struct net_device *dev)
CPMAC_SKB_SIZE,
DMA_FROM_DEVICE);
desc->hw_data = (u32)desc->data_mapping;
- desc->buflen = CPMAC_SKB_SIZE;
desc->dataflags = CPMAC_OWN;
desc->next = &priv->rx_head[(i + 1) % priv->ring_size];
desc->next->prev = desc;
--
1.7.3.3
^ permalink raw reply related
* [PATCH net-next-2.6 2/2] cpmac: fix warning length cast
From: Yoichi Yuasa @ 2010-12-13 8:18 UTC (permalink / raw)
To: David S. Miller; +Cc: yuasa, netdev, Eugene Konev
In-Reply-To: <20101213171725.2ed299cf.yuasa@linux-mips.org>
drivers/net/cpmac.c: In function 'cpmac_start_xmit':
drivers/net/cpmac.c:569: warning: comparison of distinct pointer types
lacks a cast
Signed-off-by: Yoichi Yuasa <yuasa@linux-mips.org>
---
drivers/net/cpmac.c | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c
index 8021756..3b606a5 100644
--- a/drivers/net/cpmac.c
+++ b/drivers/net/cpmac.c
@@ -180,7 +180,7 @@ struct cpmac_desc {
u32 hw_next;
u32 hw_data;
u16 bufflags;
- u16 datalen;
+ size_t datalen;
u16 dataflags;
#define CPMAC_SOP 0x8000
#define CPMAC_EOP 0x4000
@@ -554,7 +554,8 @@ fatal_error:
static int cpmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
- int queue, len;
+ int queue;
+ size_t len;
struct cpmac_desc *desc;
struct cpmac_priv *priv = netdev_priv(dev);
@@ -564,7 +565,7 @@ static int cpmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (unlikely(skb_padto(skb, ETH_ZLEN)))
return NETDEV_TX_OK;
- len = max(skb->len, ETH_ZLEN);
+ len = max_t(size_t, skb->len, ETH_ZLEN);
queue = skb_get_queue_mapping(skb);
netif_stop_subqueue(dev, queue);
--
1.7.3.3
^ permalink raw reply related
* Re: System blocks (hangs) on ifconfig up
From: Shmulik Hen @ 2010-12-13 9:14 UTC (permalink / raw)
To: netdev; +Cc: Shmulik Hen, Ben Hutchings, eric.dumazet, shemminger
In-Reply-To: <1292194983.3136.294.camel@localhost>
On 12/13/2010 01:03 AM, Ben Hutchings wrote:
> On Sun, 2010-12-12 at 17:00 +0200, Shmulik Hen wrote:
>> Hello,
>>
>> My system is Ubuntu 10.04, running kernel 2.6.32-26-generic.
>>
>> Whenever I try to bring up a specific ethernet interface for the second
>> time, my
>> system becomes unresponsive for 60 seconds - i.e. no mouse, no keyboard, no
>> screen refresh. etc.
>>
>> Looking at the driver's code, I could see that it's dev->open() method calls
>> wait_event_interruptible_timeout() with a timeout of 60 seconds - exactly
>> the delay I'm seeing.
> That seems like a stupid thing for it to do.
I agree...
>> I have narrowed the code to a bare minimum (see below - loosely based on
>> dummy.c), which only calls mdelay(10000) in it's dev->open() method, and
>> still, my system blocks for exactly 10 seconds when I run the following
>> sequence:
>>
>> > sudo ifconfig shmulik0 up
>> > sudo ifconfig shmulik0 down
>> > sudo ifconfig shmulik0 up
>>
>> At this point - the system is stuck for 10 seconds.
> Bringing an interface up or down is a synchronous operation and is
> serialised with most other network configuration operations. So this is
> the expected behaviour.
>
> Ben.
But why does this happen only the second time I run ifconfig up?
How come the entire system is totally frozen?
I can't even switch to other applications running. If I run 'top' in another
console, it stops refreshing for the entire period.
I'll try to explain better;
The driver I'm referring to is part of an embedded system development kit.
It runs on the controlling side, which may be a PC or some Linux embedded
system. It exposes a virtual interface that allows to communicate via
ethernet connection to a remote board, and performs the firmware download
to that board.
Unfortunately, the firmware download stage is done during dev->open() of
this virtual interface. The call to wait_event_interruptible_timeout()
is there to make sure the boot process of the remote board is complete via a
message. If all goes well the first time, there is no delay, but if the
operation
fails for any reason the first time, and a second attempt is made (another
ifconfig up), we see the freezing.
Since this driver is (mostly) closed source, I had to try and reproduce
the situation
in an all open-source driver - this is the sample code I attached to my
original
message. The call to mdelay() there is meant to simulate the delay of
the original
driver - it schedules.
Obviously, the correct way to fix this is to separate the firmware
download part
from the dev->open() method, but this is not as simple as it may sound - I'm
currently working on this. In the mean time I'm looking for a simpler
solution
(or answer) to our problem.
I'll appreciate any insight on this matter.
Thanks in advance,
Shmulik Hen.
^ permalink raw reply
* Re: set vlan CFI and TPID
From: Jesse Gross @ 2010-12-13 9:16 UTC (permalink / raw)
To: hong zhiyi; +Cc: netdev
In-Reply-To: <AANLkTimRZezo4WYZiXfsra83AojMubrZap1d1r5KUst1@mail.gmail.com>
On Sun, Dec 12, 2010 at 6:20 PM, hong zhiyi <zhiyi.hong@gmail.com> wrote:
> On Mon, Dec 13, 2010 at 8:20 AM, Jesse Gross <jesse@nicira.com> wrote:
>> On Tue, Dec 7, 2010 at 8:04 PM, hong zhiyi <zhiyi.hong@gmail.com> wrote:
>>> Hi All,
>>>
>>> May I ask how to set the 1 bit CFI and 2 bytesTPID in the VLAN header
>>> by vconfig?
>>
>> You can't change them using vconfig. For 802.1q/Ethernet, the TPID is
>> 0x8100 and the CFI is 0.
>>
>>> and what is the meaning of the egress map and ingress map?
>>
>> These convert between the PCP bits found in the vlan header and the
>> priority field that is used internally for QoS, which you access
>> through tc.
>>
>
> Hi Jesse,
>
> Thank you for your reply.
>
> Then how can it set the value of the TPID and the CFI? Also, I do not
> understand you mentioned the *tc* means, what is the tc?
You can't really. Like I said, the values are fixed by the standard
for basic 802.1q, which is what Linux implements. You could, of
course, directly send/receive packets through a raw socket with
whatever values you like. However, other components of the kernel
that deal with vlans won't recognize them.
tc is a userspace program that (among other things) handles QoS
settings. Google should be able to turn up information on how to use
it.
^ permalink raw reply
* correct include file for restart_syscall
From: Or Gerlitz @ 2010-12-13 10:17 UTC (permalink / raw)
To: Eric W. Biederman; +Cc: Roland Dreier, netdev
Hi,
commit 26574401fef6766f6c3ca25b5c13febe662d2a32 "net: Fix ipoib rtnl_lock
sysfs deadlock" modified some flows doing rtnl_lock calls to use rtnl_trylock
/ restart_syscall, etc. It turned out that restart_syscall was included in
ipoib through linux/inet_lro.h which is an include I'd like to remove...
Is including linux/sched.h being the right thing to do? I wasn't sure as
this call is very rare, in network drivers its called only by ipoib and
bonding and it looks like bonding includes it indirectly.
Or.
^ permalink raw reply
* [GIT PULL net-next-2.6] vhost-net: tools, cleanups, optimizations
From: Michael S. Tsirkin @ 2010-12-13 10:44 UTC (permalink / raw)
To: David Miller; +Cc: kvm, virtualization, netdev, linux-kernel
Please merge the following tree for 2.6.38.
Thanks!
The following changes since commit ad1184c6cf067a13e8cb2a4e7ccc407f947027d0:
net: au1000_eth: remove unused global variable. (2010-12-11 12:01:48 -0800)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost.git vhost-net-next
Jason Wang (1):
vhost: fix typos in comment
Julia Lawall (1):
drivers/vhost/vhost.c: delete double assignment
Michael S. Tsirkin (9):
vhost: put mm after thread stop
vhost-net: batch use/unuse mm
vhost: copy_to_user -> __copy_to_user
vhost: get/put_user -> __get/__put_user
vhost: remove unused include
vhost: correctly set bits of dirty pages
vhost: better variable name in logging
vhost test module
tools/virtio: virtio_test tool
drivers/vhost/net.c | 9 +-
drivers/vhost/test.c | 320 ++++++++++++++++++++++++++++++++++
drivers/vhost/test.h | 7 +
drivers/vhost/vhost.c | 44 +++---
drivers/vhost/vhost.h | 2 +-
tools/virtio/Makefile | 12 ++
tools/virtio/linux/device.h | 2 +
tools/virtio/linux/slab.h | 2 +
tools/virtio/linux/virtio.h | 223 +++++++++++++++++++++++
tools/virtio/vhost_test/Makefile | 2 +
tools/virtio/vhost_test/vhost_test.c | 1 +
tools/virtio/virtio_test.c | 248 ++++++++++++++++++++++++++
12 files changed, 842 insertions(+), 30 deletions(-)
create mode 100644 drivers/vhost/test.c
create mode 100644 drivers/vhost/test.h
create mode 100644 tools/virtio/Makefile
create mode 100644 tools/virtio/linux/device.h
create mode 100644 tools/virtio/linux/slab.h
create mode 100644 tools/virtio/linux/virtio.h
create mode 100644 tools/virtio/vhost_test/Makefile
create mode 100644 tools/virtio/vhost_test/vhost_test.c
create mode 100644 tools/virtio/virtio_test.c
^ permalink raw reply
* Re: correct include file for restart_syscall
From: Eric W. Biederman @ 2010-12-13 10:51 UTC (permalink / raw)
To: Or Gerlitz; +Cc: Roland Dreier, netdev
In-Reply-To: <Pine.LNX.4.64.1012131211001.17382@zuben.voltaire.com>
Or Gerlitz <ogerlitz@voltaire.com> writes:
> Hi,
>
> commit 26574401fef6766f6c3ca25b5c13febe662d2a32 "net: Fix ipoib rtnl_lock
> sysfs deadlock" modified some flows doing rtnl_lock calls to use rtnl_trylock
> / restart_syscall, etc. It turned out that restart_syscall was included in
> ipoib through linux/inet_lro.h which is an include I'd like to remove...
> Is including linux/sched.h being the right thing to do? I wasn't sure as
> this call is very rare, in network drivers its called only by ipoib and
> bonding and it looks like bonding includes it indirectly.
For the definition of restart_syscall yes.
I wish I was clever enough to find a way not to need rtnl_trylock
restart_syscall but unfortunately I don't :(
Eric
^ permalink raw reply
* Re: [PATCH 2/9] drivers/net: don't use flush_scheduled_work()
From: Lennert Buytenhek @ 2010-12-13 11:22 UTC (permalink / raw)
To: Tejun Heo
Cc: linux-kernel, netdev, davem, Jay Cliburn, Michael Chan,
Divy Le Ray, e1000-devel, Vasanthy Kolluri, Samuel Ortiz,
Andrew Gallatin, Francois Romieu, Ramkrishna Vepa, Matt Carlson,
David Brownell, Shreyas Bhatewara
In-Reply-To: <1292169185-10579-3-git-send-email-tj@kernel.org>
On Sun, Dec 12, 2010 at 04:52:58PM +0100, Tejun Heo wrote:
> flush_scheduled_work() is on its way out. This patch contains simple
> conversions to replace flush_scheduled_work() usage with direct
> cancels and flushes.
>
> Directly cancel the used works on driver detach and flush them in
> other cases.
>
> The conversions are mostly straight forward and the only dangers are,
>
> * Forgetting to cancel/flush one or more used works.
>
> * Cancelling when a work should be flushed (ie. the work must be
> executed once scheduled whether the driver is detaching or not).
>
> I've gone over the changes multiple times but it would be much
> appreciated if you can review with the above points in mind.
>
> Signed-off-by: Tejun Heo <tj@kernel.org>
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: Jay Cliburn <jcliburn@gmail.com>
> Cc: Michael Chan <mchan@broadcom.com>
> Cc: Divy Le Ray <divy@chelsio.com>
> Cc: e1000-devel@lists.sourceforge.net
> Cc: Vasanthy Kolluri <vkolluri@cisco.com>
> Cc: Samuel Ortiz <samuel@sortiz.org>
> Cc: Lennert Buytenhek <buytenh@wantstofly.org>
> Cc: Andrew Gallatin <gallatin@myri.com>
> Cc: Francois Romieu <romieu@fr.zoreil.com>
> Cc: Ramkrishna Vepa <ramkrishna.vepa@exar.com>
> Cc: Matt Carlson <mcarlson@broadcom.com>
> Cc: David Brownell <dbrownell@users.sourceforge.net>
> Cc: Shreyas Bhatewara <sbhatewara@vmware.com>
> Cc: netdev@vger.kernel.org
For the mv643xx_eth part:
Acked-by: Lennert Buytenhek <buytenh@wantstofly.org>
^ permalink raw reply
* [PATCH kernel 2.6.37-rc5] axnet_cs: move id (0x1bf, 0x2328) to axnet_cs
From: Ken Kawasaki @ 2010-12-13 12:27 UTC (permalink / raw)
To: netdev
In-Reply-To: <20101114084208.b3ee991d.ken_kawasaki@spring.nifty.jp>
axnet_cs:
Accton EN2328 or compatible (id: 0x01bf, 0x2328) uses Asix chip.
So it works better with axnet_cs instead of pcnet_cs.
Signed-off-by: Ken Kawasaki <ken_kawasaki@spring.nifty.jp>
---
--- linux-2.6.37-rc5/drivers/net/pcmcia/axnet_cs.c.orig 2010-12-12 17:26:37.000000000 +0900
+++ linux-2.6.37-rc5/drivers/net/pcmcia/axnet_cs.c 2010-12-12 17:27:22.000000000 +0900
@@ -690,6 +690,7 @@ static void block_output(struct net_devi
static struct pcmcia_device_id axnet_ids[] = {
PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x016c, 0x0081),
PCMCIA_DEVICE_MANF_CARD(0x018a, 0x0301),
+ PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x2328),
PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0301),
PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0303),
PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0309),
--- linux-2.6.37-rc5/drivers/net/pcmcia/pcnet_cs.c.orig 2010-12-12 17:26:31.000000000 +0900
+++ linux-2.6.37-rc5/drivers/net/pcmcia/pcnet_cs.c 2010-12-12 17:26:58.000000000 +0900
@@ -1493,7 +1493,6 @@ static struct pcmcia_device_id pcnet_ids
PCMCIA_DEVICE_MANF_CARD(0x0149, 0x4530),
PCMCIA_DEVICE_MANF_CARD(0x0149, 0xc1ab),
PCMCIA_DEVICE_MANF_CARD(0x0186, 0x0110),
- PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x2328),
PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x8041),
PCMCIA_DEVICE_MANF_CARD(0x0213, 0x2452),
PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0300),
^ permalink raw reply
* Re: System blocks (hangs) on ifconfig up
From: Eric Dumazet @ 2010-12-13 12:37 UTC (permalink / raw)
To: Shmulik Hen; +Cc: netdev, Shmulik Hen, Ben Hutchings, shemminger
In-Reply-To: <4D05E400.7080409@trego.co.il>
Le lundi 13 décembre 2010 à 11:14 +0200, Shmulik Hen a écrit :
> On 12/13/2010 01:03 AM, Ben Hutchings wrote:
> > On Sun, 2010-12-12 at 17:00 +0200, Shmulik Hen wrote:
> >> Hello,
> >>
> >> My system is Ubuntu 10.04, running kernel 2.6.32-26-generic.
> >>
> >> Whenever I try to bring up a specific ethernet interface for the second
> >> time, my
> >> system becomes unresponsive for 60 seconds - i.e. no mouse, no keyboard, no
> >> screen refresh. etc.
> >>
> >> Looking at the driver's code, I could see that it's dev->open() method calls
> >> wait_event_interruptible_timeout() with a timeout of 60 seconds - exactly
> >> the delay I'm seeing.
> > That seems like a stupid thing for it to do.
> I agree...
> >> I have narrowed the code to a bare minimum (see below - loosely based on
> >> dummy.c), which only calls mdelay(10000) in it's dev->open() method, and
> >> still, my system blocks for exactly 10 seconds when I run the following
> >> sequence:
> >>
> >> > sudo ifconfig shmulik0 up
> >> > sudo ifconfig shmulik0 down
> >> > sudo ifconfig shmulik0 up
> >>
> >> At this point - the system is stuck for 10 seconds.
> > Bringing an interface up or down is a synchronous operation and is
> > serialised with most other network configuration operations. So this is
> > the expected behaviour.
> >
> > Ben.
> But why does this happen only the second time I run ifconfig up?
> How come the entire system is totally frozen?
> I can't even switch to other applications running. If I run 'top' in another
> console, it stops refreshing for the entire period.
>
> I'll try to explain better;
> The driver I'm referring to is part of an embedded system development kit.
> It runs on the controlling side, which may be a PC or some Linux embedded
> system. It exposes a virtual interface that allows to communicate via
> ethernet connection to a remote board, and performs the firmware download
> to that board.
> Unfortunately, the firmware download stage is done during dev->open() of
> this virtual interface. The call to wait_event_interruptible_timeout()
> is there to make sure the boot process of the remote board is complete via a
> message. If all goes well the first time, there is no delay, but if the
> operation
> fails for any reason the first time, and a second attempt is made (another
> ifconfig up), we see the freezing.
>
> Since this driver is (mostly) closed source, I had to try and reproduce
> the situation
> in an all open-source driver - this is the sample code I attached to my
> original
> message. The call to mdelay() there is meant to simulate the delay of
> the original
> driver - it schedules.
>
mdelay() does a busy wait. If you are not SMP, this means a 'freeze'
If you want to schedule, you should use msleep()
> Obviously, the correct way to fix this is to separate the firmware
> download part
> from the dev->open() method, but this is not as simple as it may sound - I'm
> currently working on this. In the mean time I'm looking for a simpler
> solution
> (or answer) to our problem.
>
> I'll appreciate any insight on this matter.
>
> Thanks in advance,
> Shmulik Hen.
^ permalink raw reply
* Re: Using net_devices with ATM/DSL
From: Florian Fainelli @ 2010-12-13 12:50 UTC (permalink / raw)
To: Philip Prindeville; +Cc: netdev
In-Reply-To: <4D05C2D3.7010306@redfish-solutions.com>
Hello,
On Monday 13 December 2010 07:53:07 Philip Prindeville wrote:
> I was trying to get this discussion rolling on linux-atm-general but didn't
> have much luck.
>
> I was wondering what the downside to having ATM/DSL interfaces use
> net_devices would be?
I think you would have to add ATM/DSL-specific extensions (ala wext) just to
extend it, specializing an atm_dev would make more sense to me.
>
> Part of the reason for wanting to do this is to have an end-point to
> send/receive netlink messages to, so that the interface can report carrier
> state transitions, bit rates, bit-error rates, SNR, attenuation,
> constellations, transmitter gain, etc.
>
> Seems simple enough.
If you want to be able to report informations from the DSL PHY, I would rather
specialize an interface called, say dsl_phy which has a list of operations for
setting/getting the DSL PHY state, low-level counters ...
The atm stack more or less already supports an ATM PHY with
atmphy_ops, but is in my opinion too limited to query chip-speficic infos.
Once that interface is well defined, adding netlink support to it should be
rather straight forward.
>
> Why not do this?
>
> Thanks,
>
> -Philip
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: System blocks (hangs) on ifconfig up
From: Shmulik Hen @ 2010-12-13 13:11 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev, Shmulik Hen, Ben Hutchings, shemminger
In-Reply-To: <1292243832.2759.1.camel@edumazet-laptop>
On 12/13/2010 02:37 PM, Eric Dumazet wrote:
>>
>> But why does this happen only the second time I run ifconfig up?
>> How come the entire system is totally frozen?
>> I can't even switch to other applications running. If I run 'top' in another
>> console, it stops refreshing for the entire period.
>>
>> I'll try to explain better;
>> The driver I'm referring to is part of an embedded system development kit.
>> It runs on the controlling side, which may be a PC or some Linux embedded
>> system. It exposes a virtual interface that allows to communicate via
>> ethernet connection to a remote board, and performs the firmware download
>> to that board.
>> Unfortunately, the firmware download stage is done during dev->open() of
>> this virtual interface. The call to wait_event_interruptible_timeout()
>> is there to make sure the boot process of the remote board is complete via a
>> message. If all goes well the first time, there is no delay, but if the
>> operation
>> fails for any reason the first time, and a second attempt is made (another
>> ifconfig up), we see the freezing.
>>
>> Since this driver is (mostly) closed source, I had to try and reproduce
>> the situation
>> in an all open-source driver - this is the sample code I attached to my
>> original
>> message. The call to mdelay() there is meant to simulate the delay of
>> the original
>> driver - it schedules.
>>
> mdelay() does a busy wait. If you are not SMP, this means a 'freeze'
>
> If you want to schedule, you should use msleep()
Correct - my bad. When I use msleep() in the sample code there is no freeze.
But I still don't get it - when using mdelay(), why does the system
freeze only
the second time but not in the first time?
And what about wait_event_interruptible_timeout()? surely it doesn't
do a busy loop - I can see the source calling schedule().
^ permalink raw reply
* [*v2 PATCH 00/22] IPVS, Network Name Space aware
From: Hans Schillstrom @ 2010-12-13 13:38 UTC (permalink / raw)
To: horms, ja, daniel.lezcano, wensong, lvs-devel, netdev,
netfilter-devel
Cc: hans, Hans Schillstrom
This patch series adds network name space support to the LVS.
REVISION
This is version 2
OVERVIEW
The patch doesn't remove or add any functionality except for netns.
For users that don't use network name space (netns) this patch is
completely transparent.
Now it's possible to run LVS in a Linux container (see lxc-tools)
i.e. a light weight visualization. For example it's possible to run
one or several lvs on a real server in their own network name spaces.
>From the LVS point of view it looks like it runs on it's own machine.
IMPLEMENTATION
Basic requirements for netns awareness
- Global variables has to be moved to dyn. allocated memory.
- No or very little performance loss
Large hash tables connection hash and service hashes still resides in
global memory with net ptr added in hash key.
Most global variables now resides in a struct ipvs { } in netns/ip_vs.h.
The size of per name space is 2004 bytes (for x86_64) and a little bit less
for 32 bit archs.
Statistics counters is now lock-free i.e. incremented per CPU,
The estimator does a sum when using it.
Procfs ip_vs_stats is also changed to reflect the "per cpu"
ex.
# cat /proc/net/ip_vs_stats
Total Incoming Outgoing Incoming Outgoing
CPU Conns Packets Packets Bytes Bytes
0 0 3 1 9D 34
1 0 1 2 49 70
2 0 1 2 34 76
3 1 2 2 70 74
~ 1 7 7 18A 18E
Conns/s Pkts/s Pkts/s Bytes/s Bytes/s
0 0 0 0 0
Algorithm files are untouched except for lblc and lblcr.
STEP BY STEP
First patch creates network name space init for all files that need it.
How ever if a new name space is created an error is returned.
This will be removed in the last patch.
When net ptr ain't available init_net will be used temporarily.
CHANGES
*v2
The patches is totally reworked so each patch compile ...
Depends on the IPv6 and Persistence Backup patch.
Common hash-table per name-space for connections and services
Stats per CPU
smaller changes in lblc and lblcr
Triggered by Julians comment:
"tcp_timeout_change should work with the new struct ip_vs_proto_data
so that tcp_state_table will go to pd->state_table
and set_tcp_state will get pd instead of pp"
PATCH SET
This patch set is based upon lvs-test-2.6 / v2.6.37-rc1
and depends upon IPVS sync patches
STATUS
untested protos
- sctp
- esp_ah
and SIP for IPv6
SUMMARY
include/net/ip_vs.h | 236 +++++++---
include/net/net_namespace.h | 2 +
include/net/netns/ip_vs.h | 144 ++++++
net/netfilter/ipvs/ip_vs_app.c | 101 +++--
net/netfilter/ipvs/ip_vs_conn.c | 156 ++++---
net/netfilter/ipvs/ip_vs_core.c | 163 +++++--
net/netfilter/ipvs/ip_vs_ctl.c | 823 +++++++++++++++++--------------
net/netfilter/ipvs/ip_vs_est.c | 157 ++++--
net/netfilter/ipvs/ip_vs_ftp.c | 57 ++-
net/netfilter/ipvs/ip_vs_lblc.c | 66 +++-
net/netfilter/ipvs/ip_vs_lblcr.c | 70 +++-
net/netfilter/ipvs/ip_vs_nfct.c | 6 +-
net/netfilter/ipvs/ip_vs_proto.c | 121 +++++-
net/netfilter/ipvs/ip_vs_proto_ah_esp.c | 35 +-
net/netfilter/ipvs/ip_vs_proto_sctp.c | 134 +++---
net/netfilter/ipvs/ip_vs_proto_tcp.c | 125 +++---
net/netfilter/ipvs/ip_vs_proto_udp.c | 102 +++--
net/netfilter/ipvs/ip_vs_sync.c | 422 +++++++++-------
18 files changed, 1900 insertions(+), 1020 deletions(-)
^ permalink raw reply
* [*v2 PATCH 01/22] IPVS: netns, add basic init per netns.
From: Hans Schillstrom @ 2010-12-13 13:38 UTC (permalink / raw)
To: horms, ja, daniel.lezcano, wensong, lvs-devel, netdev,
netfilter-devel
Cc: hans, Hans Schillstrom
In-Reply-To: <1292247510-753-1-git-send-email-hans.schillstrom@ericsson.com>
Preparation for network name-space init, in this stage
some empty functions exists.
In most files there is a check if it is root ns i.e. init_net
if (!net_eq(net, &init_net))
return ...
this will be removed by the last patch, when enabling name-space.
Signed-off-by: Hans Schillstrom <hans.schillstrom@ericsson.com>
---
include/net/ip_vs.h | 14 ++++++++
include/net/net_namespace.h | 2 +
include/net/netns/ip_vs.h | 26 +++++++++++++++
net/netfilter/ipvs/ip_vs_app.c | 32 +++++++++++++++---
net/netfilter/ipvs/ip_vs_conn.c | 50 +++++++++++++++++++++-------
net/netfilter/ipvs/ip_vs_core.c | 67 ++++++++++++++++++++++++++++++++++----
net/netfilter/ipvs/ip_vs_ctl.c | 48 ++++++++++++++++++++++-----
net/netfilter/ipvs/ip_vs_est.c | 20 +++++++++++-
net/netfilter/ipvs/ip_vs_ftp.c | 34 +++++++++++++++++--
net/netfilter/ipvs/ip_vs_lblc.c | 37 +++++++++++++++++++--
net/netfilter/ipvs/ip_vs_lblcr.c | 38 +++++++++++++++++++--
net/netfilter/ipvs/ip_vs_proto.c | 19 +++++++++++
net/netfilter/ipvs/ip_vs_sync.c | 28 ++++++++++++++++
13 files changed, 368 insertions(+), 47 deletions(-)
create mode 100644 include/net/netns/ip_vs.h
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index d858264..40b7003 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -28,6 +28,18 @@
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
#include <net/netfilter/nf_conntrack.h>
#endif
+#include <net/net_namespace.h> /* Netw namespace */
+
+/*
+ * Generic access of ipvs struct
+ */
+static inline struct netns_ipvs * net_ipvs(struct net* net) {
+#ifdef CONFIG_NET_NS
+ return net->ipvs;
+#else
+ return init_net.ipvs;
+#endif
+}
/* Connections' size value needed by ip_vs_ctl.c */
extern int ip_vs_conn_tab_size;
@@ -922,6 +934,8 @@ extern char ip_vs_backup_mcast_ifn[IP_VS_IFNAME_MAXLEN];
extern int start_sync_thread(int state, char *mcast_ifn, __u8 syncid);
extern int stop_sync_thread(int state);
extern void ip_vs_sync_conn(struct ip_vs_conn *cp);
+extern int ip_vs_sync_init(void);
+extern void ip_vs_sync_cleanup(void);
/*
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index 1bf812b..b3b4a34 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -20,6 +20,7 @@
#include <net/netns/conntrack.h>
#endif
#include <net/netns/xfrm.h>
+#include <net/netns/ip_vs.h>
struct proc_dir_entry;
struct net_device;
@@ -94,6 +95,7 @@ struct net {
#ifdef CONFIG_XFRM
struct netns_xfrm xfrm;
#endif
+ struct netns_ipvs *ipvs;
};
diff --git a/include/net/netns/ip_vs.h b/include/net/netns/ip_vs.h
new file mode 100644
index 0000000..9068d95
--- /dev/null
+++ b/include/net/netns/ip_vs.h
@@ -0,0 +1,26 @@
+/*
+ * ip_vs.h
+ *
+ * Created on: Nov 23, 2010
+ * Author: hans
+ */
+
+#ifndef IP_VS_H_
+#define IP_VS_H_
+
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/list_nulls.h>
+#include <linux/ip_vs.h>
+#include <asm/atomic.h>
+#include <linux/in.h>
+
+struct ip_vs_stats;
+struct ip_vs_sync_buff;
+struct ctl_table_header;
+
+struct netns_ipvs {
+ int inc; /* Incarnation */
+};
+
+#endif /* IP_VS_H_ */
diff --git a/net/netfilter/ipvs/ip_vs_app.c b/net/netfilter/ipvs/ip_vs_app.c
index a475ede..6d10352 100644
--- a/net/netfilter/ipvs/ip_vs_app.c
+++ b/net/netfilter/ipvs/ip_vs_app.c
@@ -264,7 +264,7 @@ static inline void vs_fix_seq(const struct ip_vs_seq *vseq, struct tcphdr *th)
* for all packets before most recent resized pkt seq.
*/
if (vseq->delta || vseq->previous_delta) {
- if(after(seq, vseq->init_seq)) {
+ if (after(seq, vseq->init_seq)) {
th->seq = htonl(seq + vseq->delta);
IP_VS_DBG(9, "%s(): added delta (%d) to seq\n",
__func__, vseq->delta);
@@ -293,7 +293,7 @@ vs_fix_ack_seq(const struct ip_vs_seq *vseq, struct tcphdr *th)
if (vseq->delta || vseq->previous_delta) {
/* since ack_seq is the number of octet that is expected
to receive next, so compare it with init_seq+delta */
- if(after(ack_seq, vseq->init_seq+vseq->delta)) {
+ if (after(ack_seq, vseq->init_seq+vseq->delta)) {
th->ack_seq = htonl(ack_seq - vseq->delta);
IP_VS_DBG(9, "%s(): subtracted delta "
"(%d) from ack_seq\n", __func__, vseq->delta);
@@ -569,15 +569,35 @@ static const struct file_operations ip_vs_app_fops = {
};
#endif
-int __init ip_vs_app_init(void)
+static int __net_init __ip_vs_app_init(struct net *net)
{
- /* we will replace it with proc_net_ipvs_create() soon */
- proc_net_fops_create(&init_net, "ip_vs_app", 0, &ip_vs_app_fops);
+ if (!net_eq(net, &init_net)) /* netns not enabled yet */
+ return -EPERM;
+
+ proc_net_fops_create(net, "ip_vs_app", 0, &ip_vs_app_fops);
return 0;
}
+static void __net_exit __ip_vs_app_cleanup(struct net *net)
+{
+ proc_net_remove(net, "ip_vs_app");
+}
+
+static struct pernet_operations ip_vs_app_ops = {
+ .init = __ip_vs_app_init,
+ .exit = __ip_vs_app_cleanup,
+};
+
+int __init ip_vs_app_init(void)
+{
+ int rv;
+
+ rv = register_pernet_subsys(&ip_vs_app_ops);
+ return rv;
+}
+
void ip_vs_app_cleanup(void)
{
- proc_net_remove(&init_net, "ip_vs_app");
+ unregister_pernet_subsys(&ip_vs_app_ops);
}
diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
index 66e4662..5a9f5f8 100644
--- a/net/netfilter/ipvs/ip_vs_conn.c
+++ b/net/netfilter/ipvs/ip_vs_conn.c
@@ -1202,11 +1202,17 @@ static void ip_vs_conn_flush(void)
}
}
-
-int __init ip_vs_conn_init(void)
+int __net_init __ip_vs_conn_init(struct net *net)
{
int idx;
+ if (!net_eq(net, &init_net)) /* netns not enabled yet */
+ return -EPERM;
+
+ /* Compute size and mask */
+ ip_vs_conn_tab_size = 1 << ip_vs_conn_tab_bits;
+ ip_vs_conn_tab_mask = ip_vs_conn_tab_size - 1;
+
/* Compute size and mask */
ip_vs_conn_tab_size = 1 << ip_vs_conn_tab_bits;
ip_vs_conn_tab_mask = ip_vs_conn_tab_size - 1;
@@ -1243,24 +1249,42 @@ int __init ip_vs_conn_init(void)
rwlock_init(&__ip_vs_conntbl_lock_array[idx].l);
}
- proc_net_fops_create(&init_net, "ip_vs_conn", 0, &ip_vs_conn_fops);
- proc_net_fops_create(&init_net, "ip_vs_conn_sync", 0, &ip_vs_conn_sync_fops);
-
- /* calculate the random value for connection hash */
- get_random_bytes(&ip_vs_conn_rnd, sizeof(ip_vs_conn_rnd));
+ proc_net_fops_create(net, "ip_vs_conn", 0, &ip_vs_conn_fops);
+ proc_net_fops_create(net, "ip_vs_conn_sync", 0, &ip_vs_conn_sync_fops);
return 0;
}
-
-
-void ip_vs_conn_cleanup(void)
+/* Cleanup and release all netns related ... */
+static void __net_exit __ip_vs_conn_cleanup(struct net *net)
{
+ if (!net_eq(net, &init_net)) /* netns not enabled yet */
+ return;
+
/* flush all the connection entries first */
ip_vs_conn_flush();
-
/* Release the empty cache */
kmem_cache_destroy(ip_vs_conn_cachep);
- proc_net_remove(&init_net, "ip_vs_conn");
- proc_net_remove(&init_net, "ip_vs_conn_sync");
+ proc_net_remove(net, "ip_vs_conn");
+ proc_net_remove(net, "ip_vs_conn_sync");
vfree(ip_vs_conn_tab);
}
+static struct pernet_operations ipvs_conn_ops = {
+ .init = __ip_vs_conn_init,
+ .exit = __ip_vs_conn_cleanup,
+};
+
+int __init ip_vs_conn_init(void)
+{
+ int rv;
+
+ rv = register_pernet_subsys(&ipvs_conn_ops);
+
+ /* calculate the random value for connection hash */
+ get_random_bytes(&ip_vs_conn_rnd, sizeof(ip_vs_conn_rnd));
+ return rv;
+}
+
+void ip_vs_conn_cleanup(void)
+{
+ unregister_pernet_subsys(&ipvs_conn_ops);
+}
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index 5287771..cc9bbce 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -41,6 +41,7 @@
#include <net/icmp.h> /* for icmp_send */
#include <net/route.h>
#include <net/ip6_checksum.h>
+#include <net/netns/generic.h> /* net_generic() */
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
@@ -68,6 +69,12 @@ EXPORT_SYMBOL(ip_vs_conn_put);
EXPORT_SYMBOL(ip_vs_get_debug_level);
#endif
+int ip_vs_net_id __read_mostly;
+#ifdef IP_VS_GENERIC_NETNS
+EXPORT_SYMBOL(ip_vs_net_id);
+#endif
+/* netns cnt used for uniqueness */
+static atomic_t ipvs_netns_cnt = ATOMIC_INIT(0);
/* ID used in ICMP lookups */
#define icmp_id(icmph) (((icmph)->un).echo.id)
@@ -1813,6 +1820,44 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
#endif
};
+/*
+ * Initialize IP Virtual Server netns mem.
+ */
+static int __net_init __ip_vs_init(struct net *net)
+{
+ struct netns_ipvs *ipvs;
+
+ if (!net_eq(net, &init_net)) {
+ pr_err("The final patch for enabling netns is missing\n");
+ return -EPERM;
+ }
+ ipvs = (struct netns_ipvs *)net_generic(net, ip_vs_net_id);
+ if (ipvs == NULL) {
+ pr_err("%s(): no memory.\n", __func__);
+ return -ENOMEM;
+ }
+ /* Incarnation counters used for creating unique names */
+ ipvs->inc = atomic_read(&ipvs_netns_cnt);
+ atomic_inc(&ipvs_netns_cnt);
+ net->ipvs = ipvs;
+ printk(KERN_INFO "IPVS: Creating netns size=%lu id=%d\n",
+ sizeof(struct netns_ipvs), ipvs->inc);
+ return 0;
+}
+
+static void __net_exit __ip_vs_cleanup(struct net *net)
+{
+ struct netns_ipvs *ipvs = net_ipvs(net);
+
+ IP_VS_DBG(10, "ipvs netns %d released\n", ipvs->inc);
+}
+
+static struct pernet_operations ipvs_core_ops = {
+ .init = __ip_vs_init,
+ .exit = __ip_vs_cleanup,
+ .id = &ip_vs_net_id,
+ .size = sizeof(struct netns_ipvs),
+};
/*
* Initialize IP Virtual Server
@@ -1821,8 +1866,11 @@ static int __init ip_vs_init(void)
{
int ret;
- ip_vs_estimator_init();
+ ret = register_pernet_subsys(&ipvs_core_ops); /* Alloc ip_vs struct */
+ if (ret < 0)
+ return ret;
+ ip_vs_estimator_init();
ret = ip_vs_control_init();
if (ret < 0) {
pr_err("can't setup control.\n");
@@ -1830,28 +1878,30 @@ static int __init ip_vs_init(void)
}
ip_vs_protocol_init();
-
ret = ip_vs_app_init();
if (ret < 0) {
pr_err("can't setup application helper.\n");
goto cleanup_protocol;
}
-
ret = ip_vs_conn_init();
if (ret < 0) {
pr_err("can't setup connection table.\n");
goto cleanup_app;
}
-
+ ret = ip_vs_sync_init();
+ if (ret < 0) {
+ pr_err("can't setup sync data.\n");
+ goto cleanup_conn;
+ }
ret = nf_register_hooks(ip_vs_ops, ARRAY_SIZE(ip_vs_ops));
if (ret < 0) {
pr_err("can't register hooks.\n");
- goto cleanup_conn;
+ goto cleanup_sync;
}
-
pr_info("ipvs loaded.\n");
return ret;
-
+ cleanup_sync:
+ ip_vs_sync_cleanup();
cleanup_conn:
ip_vs_conn_cleanup();
cleanup_app:
@@ -1861,17 +1911,20 @@ static int __init ip_vs_init(void)
ip_vs_control_cleanup();
cleanup_estimator:
ip_vs_estimator_cleanup();
+ unregister_pernet_subsys(&ipvs_core_ops); /* free ip_vs struct */
return ret;
}
static void __exit ip_vs_cleanup(void)
{
nf_unregister_hooks(ip_vs_ops, ARRAY_SIZE(ip_vs_ops));
+ ip_vs_sync_cleanup();
ip_vs_conn_cleanup();
ip_vs_app_cleanup();
ip_vs_protocol_cleanup();
ip_vs_control_cleanup();
ip_vs_estimator_cleanup();
+ unregister_pernet_subsys(&ipvs_core_ops); /* free ip_vs struct */
pr_info("ipvs unloaded.\n");
}
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index d12a13c..33511f4 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -3408,6 +3408,41 @@ static void ip_vs_genl_unregister(void)
/* End of Generic Netlink interface definitions */
+/*
+ * per netns intit/exit func.
+ */
+int __net_init __ip_vs_control_init(struct net *net)
+{
+ if (!net_eq(net, &init_net)) /* netns not enabled yet */
+ return -EPERM;
+
+ proc_net_fops_create(net, "ip_vs", 0, &ip_vs_info_fops);
+ proc_net_fops_create(net, "ip_vs_stats", 0, &ip_vs_stats_fops);
+ sysctl_header = register_net_sysctl_table(net, net_vs_ctl_path, vs_vars);
+ if (sysctl_header == NULL)
+ goto err_reg;
+ ip_vs_new_estimator(&ip_vs_stats);
+ return 0;
+
+err_reg:
+ return -ENOMEM;
+}
+
+static void __net_exit __ip_vs_control_cleanup(struct net *net)
+{
+ if (!net_eq(net, &init_net)) /* netns not enabled yet */
+ return;
+
+ ip_vs_kill_estimator(&ip_vs_stats);
+ unregister_net_sysctl_table(sysctl_header);
+ proc_net_remove(net, "ip_vs_stats");
+ proc_net_remove(net, "ip_vs");
+}
+
+static struct pernet_operations ipvs_control_ops = {
+ .init = __ip_vs_control_init,
+ .exit = __ip_vs_control_cleanup,
+};
int __init ip_vs_control_init(void)
{
@@ -3439,12 +3474,9 @@ int __init ip_vs_control_init(void)
return ret;
}
- proc_net_fops_create(&init_net, "ip_vs", 0, &ip_vs_info_fops);
- proc_net_fops_create(&init_net, "ip_vs_stats",0, &ip_vs_stats_fops);
-
- sysctl_header = register_sysctl_paths(net_vs_ctl_path, vs_vars);
-
- ip_vs_new_estimator(&ip_vs_stats);
+ ret = register_pernet_subsys(&ipvs_control_ops);
+ if (ret)
+ return ret;
/* Hook the defense timer */
schedule_delayed_work(&defense_work, DEFENSE_TIMER_PERIOD);
@@ -3461,9 +3493,7 @@ void ip_vs_control_cleanup(void)
cancel_rearming_delayed_work(&defense_work);
cancel_work_sync(&defense_work.work);
ip_vs_kill_estimator(&ip_vs_stats);
- unregister_sysctl_table(sysctl_header);
- proc_net_remove(&init_net, "ip_vs_stats");
- proc_net_remove(&init_net, "ip_vs");
+ unregister_pernet_subsys(&ipvs_control_ops);
ip_vs_genl_unregister();
nf_unregister_sockopt(&ip_vs_sockopts);
LeaveFunction(2);
diff --git a/net/netfilter/ipvs/ip_vs_est.c b/net/netfilter/ipvs/ip_vs_est.c
index ff28801..7417a0c 100644
--- a/net/netfilter/ipvs/ip_vs_est.c
+++ b/net/netfilter/ipvs/ip_vs_est.c
@@ -157,13 +157,31 @@ void ip_vs_zero_estimator(struct ip_vs_stats *stats)
est->outbps = 0;
}
+static int __net_init __ip_vs_estimator_init(struct net *net)
+{
+ if (!net_eq(net, &init_net)) /* netns not enabled yet */
+ return -EPERM;
+
+ return 0;
+}
+
+static struct pernet_operations ip_vs_app_ops = {
+ .init = __ip_vs_estimator_init,
+};
+
int __init ip_vs_estimator_init(void)
{
+ int rv;
+
+ rv = register_pernet_subsys(&ip_vs_app_ops);
+ if (rv < 0)
+ return rv;
mod_timer(&est_timer, jiffies + 2 * HZ);
- return 0;
+ return rv;
}
void ip_vs_estimator_cleanup(void)
{
del_timer_sync(&est_timer);
+ unregister_pernet_subsys(&ip_vs_app_ops);
}
diff --git a/net/netfilter/ipvs/ip_vs_ftp.c b/net/netfilter/ipvs/ip_vs_ftp.c
index 84aef65..0e762f3 100644
--- a/net/netfilter/ipvs/ip_vs_ftp.c
+++ b/net/netfilter/ipvs/ip_vs_ftp.c
@@ -399,15 +399,17 @@ static struct ip_vs_app ip_vs_ftp = {
.pkt_in = ip_vs_ftp_in,
};
-
/*
- * ip_vs_ftp initialization
+ * per netns ip_vs_ftp initialization
*/
-static int __init ip_vs_ftp_init(void)
+static int __net_init __ip_vs_ftp_init(struct net *net)
{
int i, ret;
struct ip_vs_app *app = &ip_vs_ftp;
+ if (!net_eq(net, &init_net)) /* netns not enabled yet */
+ return -EPERM;
+
ret = register_ip_vs_app(app);
if (ret)
return ret;
@@ -427,14 +429,38 @@ static int __init ip_vs_ftp_init(void)
return ret;
}
+/*
+ * netns exit
+ */
+static void __ip_vs_ftp_exit(struct net *net)
+{
+ struct ip_vs_app *app = &ip_vs_ftp;
+
+ if (!net_eq(net, &init_net)) /* netns not enabled yet */
+ return;
+
+ unregister_ip_vs_app(app);
+}
+
+static struct pernet_operations ip_vs_ftp_ops = {
+ .init = __ip_vs_ftp_init,
+ .exit = __ip_vs_ftp_exit,
+};
+int __init ip_vs_ftp_init(void)
+{
+ int rv;
+
+ rv = register_pernet_subsys(&ip_vs_ftp_ops);
+ return rv;
+}
/*
* ip_vs_ftp finish.
*/
static void __exit ip_vs_ftp_exit(void)
{
- unregister_ip_vs_app(&ip_vs_ftp);
+ unregister_pernet_subsys(&ip_vs_ftp_ops);
}
diff --git a/net/netfilter/ipvs/ip_vs_lblc.c b/net/netfilter/ipvs/ip_vs_lblc.c
index 9323f89..84278fb 100644
--- a/net/netfilter/ipvs/ip_vs_lblc.c
+++ b/net/netfilter/ipvs/ip_vs_lblc.c
@@ -543,23 +543,54 @@ static struct ip_vs_scheduler ip_vs_lblc_scheduler =
.schedule = ip_vs_lblc_schedule,
};
+/*
+ * per netns init.
+ */
+static int __net_init __ip_vs_lblc_init(struct net *net)
+{
+ if (!net_eq(net, &init_net)) /* netns not enabled yet */
+ return -EPERM;
+
+ sysctl_header = register_net_sysctl_table(net, net_vs_ctl_path,
+ vs_vars_table);
+ if (!sysctl_header)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static void __net_exit __ip_vs_lblc_exit(struct net *net)
+{
+ if (!net_eq(net, &init_net)) /* netns not enabled yet */
+ return;
+
+ unregister_net_sysctl_table(sysctl_header);
+}
+
+static struct pernet_operations ip_vs_lblc_ops = {
+ .init = __ip_vs_lblc_init,
+ .exit = __ip_vs_lblc_exit,
+};
static int __init ip_vs_lblc_init(void)
{
int ret;
- sysctl_header = register_sysctl_paths(net_vs_ctl_path, vs_vars_table);
+ ret = register_pernet_subsys(&ip_vs_lblc_ops);
+ if (ret)
+ return ret;
+
ret = register_ip_vs_scheduler(&ip_vs_lblc_scheduler);
if (ret)
- unregister_sysctl_table(sysctl_header);
+ unregister_pernet_subsys(&ip_vs_lblc_ops);
return ret;
}
static void __exit ip_vs_lblc_cleanup(void)
{
- unregister_sysctl_table(sysctl_header);
unregister_ip_vs_scheduler(&ip_vs_lblc_scheduler);
+ unregister_pernet_subsys(&ip_vs_lblc_ops);
}
diff --git a/net/netfilter/ipvs/ip_vs_lblcr.c b/net/netfilter/ipvs/ip_vs_lblcr.c
index dbeed8e..7c7396a 100644
--- a/net/netfilter/ipvs/ip_vs_lblcr.c
+++ b/net/netfilter/ipvs/ip_vs_lblcr.c
@@ -744,23 +744,53 @@ static struct ip_vs_scheduler ip_vs_lblcr_scheduler =
.schedule = ip_vs_lblcr_schedule,
};
+/*
+ * per netns init.
+ */
+static int __net_init __ip_vs_lblcr_init(struct net *net)
+{
+ if (!net_eq(net, &init_net)) /* netns not enabled yet */
+ return -EPERM;
+
+ sysctl_header = register_net_sysctl_table(net, net_vs_ctl_path,
+ vs_vars_table);
+ if (!sysctl_header)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static void __net_exit __ip_vs_lblcr_exit(struct net *net)
+{
+ if (!net_eq(net, &init_net)) /* netns not enabled yet */
+ return;
+
+ unregister_net_sysctl_table(sysctl_header);
+}
+
+static struct pernet_operations ip_vs_lblcr_ops = {
+ .init = __ip_vs_lblcr_init,
+ .exit = __ip_vs_lblcr_exit,
+};
static int __init ip_vs_lblcr_init(void)
{
int ret;
- sysctl_header = register_sysctl_paths(net_vs_ctl_path, vs_vars_table);
+ ret = register_pernet_subsys(&ip_vs_lblcr_ops);
+ if (ret)
+ return ret;
+
ret = register_ip_vs_scheduler(&ip_vs_lblcr_scheduler);
if (ret)
- unregister_sysctl_table(sysctl_header);
+ unregister_pernet_subsys(&ip_vs_lblcr_ops);
return ret;
}
-
static void __exit ip_vs_lblcr_cleanup(void)
{
- unregister_sysctl_table(sysctl_header);
unregister_ip_vs_scheduler(&ip_vs_lblcr_scheduler);
+ unregister_pernet_subsys(&ip_vs_lblcr_ops);
}
diff --git a/net/netfilter/ipvs/ip_vs_proto.c b/net/netfilter/ipvs/ip_vs_proto.c
index c539983..27bf034 100644
--- a/net/netfilter/ipvs/ip_vs_proto.c
+++ b/net/netfilter/ipvs/ip_vs_proto.c
@@ -236,6 +236,23 @@ ip_vs_tcpudp_debug_packet(int af, struct ip_vs_protocol *pp,
ip_vs_tcpudp_debug_packet_v4(pp, skb, offset, msg);
}
+/*
+ * per network name-space init
+ */
+static int __net_init __ip_vs_protocol_init(struct net *net)
+{
+ return 0;
+}
+
+static void __net_exit __ip_vs_protocol_cleanup(struct net *net)
+{
+ /* empty */
+}
+
+static struct pernet_operations ipvs_proto_ops = {
+ .init = __ip_vs_protocol_init,
+ .exit = __ip_vs_protocol_cleanup,
+};
int __init ip_vs_protocol_init(void)
{
@@ -265,6 +282,7 @@ int __init ip_vs_protocol_init(void)
REGISTER_PROTOCOL(&ip_vs_protocol_esp);
#endif
pr_info("Registered protocols (%s)\n", &protocols[2]);
+ return register_pernet_subsys(&ipvs_proto_ops);
return 0;
}
@@ -275,6 +293,7 @@ void ip_vs_protocol_cleanup(void)
struct ip_vs_protocol *pp;
int i;
+ unregister_pernet_subsys(&ipvs_proto_ops);
/* unregister all the ipvs protocols */
for (i = 0; i < IP_VS_PROTO_TAB_SIZE; i++) {
while ((pp = ip_vs_proto_table[i]) != NULL)
diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c
index c1c167a..ea390f8 100644
--- a/net/netfilter/ipvs/ip_vs_sync.c
+++ b/net/netfilter/ipvs/ip_vs_sync.c
@@ -1639,3 +1639,31 @@ int stop_sync_thread(int state)
return 0;
}
+
+/*
+ * Initialize data struct for each netns
+ */
+static int __net_init __ip_vs_sync_init(struct net *net)
+{
+ return 0;
+}
+
+static void __ip_vs_sync_cleanup(struct net *net)
+{
+ return;
+}
+static struct pernet_operations ipvs_sync_ops = {
+ .init = __ip_vs_sync_init,
+ .exit = __ip_vs_sync_cleanup,
+};
+
+
+int __init ip_vs_sync_init(void)
+{
+ return register_pernet_subsys(&ipvs_sync_ops);
+}
+
+void __exit ip_vs_sync_cleanup(void)
+{
+ unregister_pernet_subsys(&ipvs_sync_ops);
+}
--
1.7.2.3
^ permalink raw reply related
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