* Re: [PATCH 3/8] [I/OAT] Setup the networking subsystem as a DMA client
From: Andrew Morton @ 2006-03-11 8:56 UTC (permalink / raw)
To: Chris Leech; +Cc: linux-kernel, netdev
In-Reply-To: <20060311022924.3950.33580.stgit@gitlost.site>
Chris Leech <christopher.leech@intel.com> wrote:
>
There seems to be a small race here.
> +static void net_dma_rebalance(void)
> +{
> + unsigned int cpu, i, n;
> + struct dma_chan *chan;
> +
> + lock_cpu_hotplug();
> +
> + if (net_dma_count == 0) {
> + for_each_online_cpu(cpu)
> + rcu_assign_pointer(per_cpu(softnet_data.net_dma, cpu), NULL);
> + unlock_cpu_hotplug();
> + return;
> + }
If some other CPU does netdev_dma_event(DMA_RESOURCE_REMOVED) now
> + i = 0;
> + cpu = first_cpu(cpu_online_map);
> +
> + rcu_read_lock();
> + list_for_each_entry(chan, &net_dma_client->channels, client_node) {
> + n = ((num_online_cpus() / net_dma_count)
> + + (i < (num_online_cpus() % net_dma_count) ? 1 : 0));
This will get a divide-by-zero.
> + while(n) {
> + per_cpu(softnet_data.net_dma, cpu) = chan;
> + cpu = next_cpu(cpu, cpu_online_map);
> + n--;
> + }
> + i++;
> + }
> + rcu_read_unlock();
> +
> + unlock_cpu_hotplug();
> +}
> +
> +/**
> + * netdev_dma_event - event callback for the net_dma_client
> + * @client: should always be net_dma_client
> + * @chan:
> + * @event:
> + */
> +static void netdev_dma_event(struct dma_client *client, struct dma_chan *chan,
> + enum dma_event event)
> +{
> + switch (event) {
> + case DMA_RESOURCE_ADDED:
> + net_dma_count++;
> + net_dma_rebalance();
> + break;
> + case DMA_RESOURCE_REMOVED:
> + net_dma_count--;
> + net_dma_rebalance();
> + break;
> + default:
> + break;
> + }
> +}
^ permalink raw reply
* Re: [PATCH 3/8] [I/OAT] Setup the networking subsystem as a DMA client
From: Andrew Morton @ 2006-03-11 9:00 UTC (permalink / raw)
To: Chris Leech; +Cc: linux-kernel, netdev
In-Reply-To: <20060311022924.3950.33580.stgit@gitlost.site>
Chris Leech <christopher.leech@intel.com> wrote:
>
> +#ifdef CONFIG_NET_DMA
> +#include <linux/dmaengine.h>
> +#endif
There are still a number of instances of this in the patch series. Did you
decide to keep the ifdefs in there for some reason?
^ permalink raw reply
* Re: [PATCH 8/8] [I/OAT] TCP recv offload to I/OAT
From: Andrew Morton @ 2006-03-11 9:41 UTC (permalink / raw)
To: Chris Leech; +Cc: linux-kernel, netdev
In-Reply-To: <20060311022936.3950.86896.stgit@gitlost.site>
Chris Leech <christopher.leech@intel.com> wrote:
>
> Locks down user pages and sets up for DMA in tcp_recvmsg, then calls
> dma_async_try_early_copy in tcp_v4_do_rcv
All those ifdefs are still there. They really do put a maintenance burden
on, of all places, net/ipv4/tcp.c. Please find a way of abstracting out
the conceptual additions which IOAT makes to TCP and to wrap that into
inline functions, etc. See how tidily NF_HOOK() has inserted things into
the net stack.
Also, for something which is billed as an performance enhancement,
benchmark numbers are the key thing which we need to judge the desirability
of these changes. What is the plan there?
Thanks.
^ permalink raw reply
* Re: [UPDATED PATCH] Re: Re: [Patch 7/7] Generic netlink interface (delay accounting)
From: jamal @ 2006-03-11 13:30 UTC (permalink / raw)
To: balbir; +Cc: Shailabh Nagar, netdev, linux-kernel, lse-tech
In-Reply-To: <20060310163927.GA6537@in.ibm.com>
On Fri, 2006-10-03 at 22:09 +0530, Balbir Singh wrote:
> On Fri, Mar 10, 2006 at 09:53:53AM -0500, jamal wrote:
> > On kernel->user (in the case of response to #a or async notifiation as
> > in #b) you really dont need to specify the TG/PID since they appear in
> > the STATS etc.
>
> I see your point now. I am looking at other users of netlink like
> rtnetlink and I see the classical usage.
>
> We can implement TLV's in our code, but for the most part the data we exchange
> between the user <-> kernel has all the TLV's listed in the enum above.
>
> The major differnece is the type (pid/tgid). Hence we created a structure
> (taskstats) instead of using TLV's.
Something to remember:
1) TLVs are essentially giving you the flexibility to send optionally
appearing elements. It is up to the receiver (in the kernel or user
space) to check for the presence of mandatory elements or execute things
depending on the presence of certain TLVs. Example in your case:
if the tgid TLV appears then the user is requesting for that TLV
if the pid appears then they are requesting for that
if both appear then it is the && of the two.
You should always ignore TLVs you dont understand - to allow for forward
compatibility.
2) The "T" part is essentially also encoding (semantically) what size
the value is; the "L" part is useful for validation. So the receiver
will always know what the size of the TLV is by definition and uses the
L to make sure it is the right size. Reject what is of the wrong size.
cheers,
jamal
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
^ permalink raw reply
* [git patches] net driver fixes
From: Jeff Garzik @ 2006-03-11 18:40 UTC (permalink / raw)
To: Andrew Morton, Linus Torvalds; +Cc: netdev, linux-kernel
Please pull from 'upstream-fixes' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git
to receive the following updates:
drivers/net/3c509.c | 13 ++++++++-----
drivers/net/Kconfig | 3 ++-
drivers/net/de620.c | 2 +-
drivers/net/dl2k.c | 25 +++++++++++++++----------
drivers/net/e1000/e1000_main.c | 2 +-
drivers/net/sky2.c | 32 +++++++++++++++++++++-----------
drivers/net/tulip/de2104x.c | 26 +++++++++++++-------------
7 files changed, 61 insertions(+), 42 deletions(-)
Andrew Morton:
3c509: bus registration fix
David S. Miller:
Wrong return value corrupts free object in e1000 driver
Francois Romieu:
de2104x: prevent interrupt before the interrupt handler is registered
de2104x: fix the TX watchdog
Jesper Juhl:
NE2000 Kconfig help entry improvement
Jon Mason:
dl2k: DMA freeing error
Sam Ravnborg:
de620: fix section mismatch warning
Stephen Hemminger:
sky2: not random enough
sky2: force early transmit interrupts
sky2: truncate oversize packets
diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c
index 824e430..830528d 100644
--- a/drivers/net/3c509.c
+++ b/drivers/net/3c509.c
@@ -1574,6 +1574,7 @@ MODULE_LICENSE("GPL");
static int __init el3_init_module(void)
{
+ int ret = 0;
el3_cards = 0;
if (debug >= 0)
@@ -1589,14 +1590,16 @@ static int __init el3_init_module(void)
}
#ifdef CONFIG_EISA
- if (eisa_driver_register (&el3_eisa_driver) < 0) {
- eisa_driver_unregister (&el3_eisa_driver);
- }
+ ret = eisa_driver_register(&el3_eisa_driver);
#endif
#ifdef CONFIG_MCA
- mca_register_driver(&el3_mca_driver);
+ {
+ int err = mca_register_driver(&el3_mca_driver);
+ if (ret == 0)
+ ret = err;
+ }
#endif
- return 0;
+ return ret;
}
static void __exit el3_cleanup_module(void)
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index e45a8f9..aa633fa 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1087,7 +1087,8 @@ config NE2000
without a specific driver are compatible with NE2000.
If you have a PCI NE2000 card however, say N here and Y to "PCI
- NE2000 support", above. If you have a NE2000 card and are running on
+ NE2000 and clone support" under "EISA, VLB, PCI and on board
+ controllers" below. If you have a NE2000 card and are running on
an MCA system (a bus system used on some IBM PS/2 computers and
laptops), say N here and Y to "NE/2 (ne2000 MCA version) support",
below.
diff --git a/drivers/net/de620.c b/drivers/net/de620.c
index 0069f5f..22fc5b8 100644
--- a/drivers/net/de620.c
+++ b/drivers/net/de620.c
@@ -1012,7 +1012,7 @@ static int __init read_eeprom(struct net
#ifdef MODULE
static struct net_device *de620_dev;
-int init_module(void)
+int __init init_module(void)
{
de620_dev = de620_probe(-1);
if (IS_ERR(de620_dev))
diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c
index 430c628..fb9dae3 100644
--- a/drivers/net/dl2k.c
+++ b/drivers/net/dl2k.c
@@ -50,8 +50,8 @@
*/
#define DRV_NAME "D-Link DL2000-based linux driver"
-#define DRV_VERSION "v1.17a"
-#define DRV_RELDATE "2002/10/04"
+#define DRV_VERSION "v1.17b"
+#define DRV_RELDATE "2006/03/10"
#include "dl2k.h"
static char version[] __devinitdata =
@@ -765,7 +765,7 @@ rio_free_tx (struct net_device *dev, int
break;
skb = np->tx_skbuff[entry];
pci_unmap_single (np->pdev,
- np->tx_ring[entry].fraginfo,
+ np->tx_ring[entry].fraginfo & 0xffffffffffff,
skb->len, PCI_DMA_TODEVICE);
if (irq)
dev_kfree_skb_irq (skb);
@@ -892,14 +892,16 @@ receive_packet (struct net_device *dev)
/* Small skbuffs for short packets */
if (pkt_len > copy_thresh) {
- pci_unmap_single (np->pdev, desc->fraginfo,
+ pci_unmap_single (np->pdev,
+ desc->fraginfo & 0xffffffffffff,
np->rx_buf_sz,
PCI_DMA_FROMDEVICE);
skb_put (skb = np->rx_skbuff[entry], pkt_len);
np->rx_skbuff[entry] = NULL;
} else if ((skb = dev_alloc_skb (pkt_len + 2)) != NULL) {
pci_dma_sync_single_for_cpu(np->pdev,
- desc->fraginfo,
+ desc->fraginfo &
+ 0xffffffffffff,
np->rx_buf_sz,
PCI_DMA_FROMDEVICE);
skb->dev = dev;
@@ -910,7 +912,8 @@ receive_packet (struct net_device *dev)
pkt_len, 0);
skb_put (skb, pkt_len);
pci_dma_sync_single_for_device(np->pdev,
- desc->fraginfo,
+ desc->fraginfo &
+ 0xffffffffffff,
np->rx_buf_sz,
PCI_DMA_FROMDEVICE);
}
@@ -1796,8 +1799,9 @@ rio_close (struct net_device *dev)
np->rx_ring[i].fraginfo = 0;
skb = np->rx_skbuff[i];
if (skb) {
- pci_unmap_single (np->pdev, np->rx_ring[i].fraginfo,
- skb->len, PCI_DMA_FROMDEVICE);
+ pci_unmap_single(np->pdev,
+ np->rx_ring[i].fraginfo & 0xffffffffffff,
+ skb->len, PCI_DMA_FROMDEVICE);
dev_kfree_skb (skb);
np->rx_skbuff[i] = NULL;
}
@@ -1805,8 +1809,9 @@ rio_close (struct net_device *dev)
for (i = 0; i < TX_RING_SIZE; i++) {
skb = np->tx_skbuff[i];
if (skb) {
- pci_unmap_single (np->pdev, np->tx_ring[i].fraginfo,
- skb->len, PCI_DMA_TODEVICE);
+ pci_unmap_single(np->pdev,
+ np->tx_ring[i].fraginfo & 0xffffffffffff,
+ skb->len, PCI_DMA_TODEVICE);
dev_kfree_skb (skb);
np->tx_skbuff[i] = NULL;
}
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 5b7d0f4..4c4db96 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -2917,7 +2917,7 @@ e1000_xmit_frame(struct sk_buff *skb, st
if (!__pskb_pull_tail(skb, pull_size)) {
printk(KERN_ERR "__pskb_pull_tail failed.\n");
dev_kfree_skb_any(skb);
- return -EFAULT;
+ return NETDEV_TX_OK;
}
len = skb->len - skb->data_len;
}
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 72c1630..7326036 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -74,7 +74,7 @@
#define TX_RING_SIZE 512
#define TX_DEF_PENDING (TX_RING_SIZE - 1)
#define TX_MIN_PENDING 64
-#define MAX_SKB_TX_LE (4 + 2*MAX_SKB_FRAGS)
+#define MAX_SKB_TX_LE (4 + (sizeof(dma_addr_t)/sizeof(u32))*MAX_SKB_FRAGS)
#define STATUS_RING_SIZE 2048 /* 2 ports * (TX + 2*RX) */
#define STATUS_LE_BYTES (STATUS_RING_SIZE*sizeof(struct sky2_status_le))
@@ -622,8 +622,8 @@ static void sky2_mac_init(struct sky2_hw
/* Configure Rx MAC FIFO */
sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR);
- sky2_write16(hw, SK_REG(port, RX_GMF_CTRL_T),
- GMF_RX_CTRL_DEF);
+ sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
+ GMF_OPER_ON | GMF_RX_F_FL_ON);
/* Flush Rx MAC FIFO on any flow control or error */
sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR);
@@ -995,6 +995,10 @@ static int sky2_rx_start(struct sky2_por
sky2_rx_add(sky2, re->mapaddr);
}
+ /* Truncate oversize frames */
+ sky2_write16(hw, SK_REG(sky2->port, RX_GMF_TR_THR), sky2->rx_bufsize - 8);
+ sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_ON);
+
/* Tell chip about available buffers */
sky2_write16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX), sky2->rx_put);
sky2->rx_last_put = sky2_read16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX));
@@ -1145,6 +1149,7 @@ static int sky2_xmit_frame(struct sk_buf
struct sky2_tx_le *le = NULL;
struct tx_ring_info *re;
unsigned i, len;
+ int avail;
dma_addr_t mapping;
u32 addr64;
u16 mss;
@@ -1287,12 +1292,16 @@ static int sky2_xmit_frame(struct sk_buf
re->idx = sky2->tx_prod;
le->ctrl |= EOP;
+ avail = tx_avail(sky2);
+ if (mss != 0 || avail < TX_MIN_PENDING) {
+ le->ctrl |= FRC_STAT;
+ if (avail <= MAX_SKB_TX_LE)
+ netif_stop_queue(dev);
+ }
+
sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod,
&sky2->tx_last_put, TX_RING_SIZE);
- if (tx_avail(sky2) <= MAX_SKB_TX_LE)
- netif_stop_queue(dev);
-
out_unlock:
spin_unlock(&sky2->tx_lock);
@@ -1707,10 +1716,12 @@ static void sky2_tx_timeout(struct net_d
#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
-/* Want receive buffer size to be multiple of 64 bits, and incl room for vlan */
+/* Want receive buffer size to be multiple of 64 bits
+ * and incl room for vlan and truncation
+ */
static inline unsigned sky2_buf_size(int mtu)
{
- return roundup(mtu + ETH_HLEN + 4, 8);
+ return roundup(mtu + ETH_HLEN + VLAN_HLEN, 8) + 8;
}
static int sky2_change_mtu(struct net_device *dev, int new_mtu)
@@ -1793,7 +1804,7 @@ static struct sk_buff *sky2_receive(stru
if (!(status & GMR_FS_RX_OK))
goto resubmit;
- if ((status >> 16) != length || length > sky2->rx_bufsize)
+ if (length > sky2->netdev->mtu + ETH_HLEN)
goto oversize;
if (length < copybreak) {
@@ -3243,8 +3254,7 @@ static int __devinit sky2_probe(struct p
}
}
- err = request_irq(pdev->irq, sky2_intr, SA_SHIRQ | SA_SAMPLE_RANDOM,
- DRV_NAME, hw);
+ err = request_irq(pdev->irq, sky2_intr, SA_SHIRQ, DRV_NAME, hw);
if (err) {
printk(KERN_ERR PFX "%s: cannot assign irq %d\n",
pci_name(pdev), pdev->irq);
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
index d7fb3ff..2d0cfbc 100644
--- a/drivers/net/tulip/de2104x.c
+++ b/drivers/net/tulip/de2104x.c
@@ -1362,7 +1362,6 @@ static int de_open (struct net_device *d
{
struct de_private *de = dev->priv;
int rc;
- unsigned long flags;
if (netif_msg_ifup(de))
printk(KERN_DEBUG "%s: enabling interface\n", dev->name);
@@ -1376,18 +1375,20 @@ static int de_open (struct net_device *d
return rc;
}
- rc = de_init_hw(de);
- if (rc) {
- printk(KERN_ERR "%s: h/w init failure, err=%d\n",
- dev->name, rc);
- goto err_out_free;
- }
+ dw32(IntrMask, 0);
rc = request_irq(dev->irq, de_interrupt, SA_SHIRQ, dev->name, dev);
if (rc) {
printk(KERN_ERR "%s: IRQ %d request failure, err=%d\n",
dev->name, dev->irq, rc);
- goto err_out_hw;
+ goto err_out_free;
+ }
+
+ rc = de_init_hw(de);
+ if (rc) {
+ printk(KERN_ERR "%s: h/w init failure, err=%d\n",
+ dev->name, rc);
+ goto err_out_free_irq;
}
netif_start_queue(dev);
@@ -1395,11 +1396,8 @@ static int de_open (struct net_device *d
return 0;
-err_out_hw:
- spin_lock_irqsave(&de->lock, flags);
- de_stop_hw(de);
- spin_unlock_irqrestore(&de->lock, flags);
-
+err_out_free_irq:
+ free_irq(dev->irq, dev);
err_out_free:
de_free_rings(de);
return rc;
@@ -1455,6 +1453,8 @@ static void de_tx_timeout (struct net_de
synchronize_irq(dev->irq);
de_clean_rings(de);
+ de_init_rings(de);
+
de_init_hw(de);
netif_wake_queue(dev);
^ permalink raw reply related
* [PATCH] Nearly complete kzalloc cleanup for net/ipv6
From: Ingo Oeser @ 2006-03-11 20:36 UTC (permalink / raw)
To: YOSHIFUJI Hideaki / 吉藤英明
Cc: David Miller, linux-kernel, netdev
From: Ingo Oeser <ioe-lkml@rameria.de>
Stupidly use kzalloc() instead of kmalloc()/memset()
everywhere where this is possible in net/ipv6/*.c .
Signed-off-by: Ingo Oeser <ioe-lkml@rameria.de>
---
Hi,
I'm going to refactor some of the simple cases to reduce code
duplication which will depend on this patch.
net/ipv6/reassambly.c will get a separate patch,
since I refactored it a little bit.
The netfilter part is NOT included, because Harald should see these, too.
Patch is against net-2.6.17
Regards
Ingo Oeser
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index 8ff7147..b876a10 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -354,12 +354,10 @@ static int ah6_init_state(struct xfrm_st
if (x->encap)
goto error;
- ahp = kmalloc(sizeof(*ahp), GFP_KERNEL);
+ ahp = kzalloc(sizeof(*ahp), GFP_KERNEL);
if (ahp == NULL)
return -ENOMEM;
- memset(ahp, 0, sizeof(*ahp));
-
ahp->key = x->aalg->alg_key;
ahp->key_len = (x->aalg->alg_key_len+7)/8;
ahp->tfm = crypto_alloc_tfm(x->aalg->alg_name, 0);
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c
index 840a33d..39ec528 100644
--- a/net/ipv6/anycast.c
+++ b/net/ipv6/anycast.c
@@ -308,7 +308,7 @@ int ipv6_dev_ac_inc(struct net_device *d
* not found: create a new one.
*/
- aca = kmalloc(sizeof(struct ifacaddr6), GFP_ATOMIC);
+ aca = kzalloc(sizeof(struct ifacaddr6), GFP_ATOMIC);
if (aca == NULL) {
err = -ENOMEM;
@@ -322,8 +322,6 @@ int ipv6_dev_ac_inc(struct net_device *d
goto out;
}
- memset(aca, 0, sizeof(struct ifacaddr6));
-
ipv6_addr_copy(&aca->aca_addr, addr);
aca->aca_idev = idev;
aca->aca_rt = rt;
@@ -550,7 +548,7 @@ static int ac6_seq_open(struct inode *in
{
struct seq_file *seq;
int rc = -ENOMEM;
- struct ac6_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
+ struct ac6_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL);
if (!s)
goto out;
@@ -561,7 +559,6 @@ static int ac6_seq_open(struct inode *in
seq = file->private_data;
seq->private = s;
- memset(s, 0, sizeof(*s));
out:
return rc;
out_kfree:
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index aa7f100..3dcaac7 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -305,12 +305,10 @@ static int esp6_init_state(struct xfrm_s
if (x->encap)
goto error;
- esp = kmalloc(sizeof(*esp), GFP_KERNEL);
+ esp = kzalloc(sizeof(*esp), GFP_KERNEL);
if (esp == NULL)
return -ENOMEM;
- memset(esp, 0, sizeof(*esp));
-
if (x->aalg) {
struct xfrm_algo_desc *aalg_desc;
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index 69cbe8a..f9ca639 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -287,10 +287,9 @@ fl_create(struct in6_flowlabel_req *freq
int err;
err = -ENOMEM;
- fl = kmalloc(sizeof(*fl), GFP_KERNEL);
+ fl = kzalloc(sizeof(*fl), GFP_KERNEL);
if (fl == NULL)
goto done;
- memset(fl, 0, sizeof(*fl));
olen = optlen - CMSG_ALIGN(sizeof(*freq));
if (olen > 0) {
@@ -663,7 +662,7 @@ static int ip6fl_seq_open(struct inode *
{
struct seq_file *seq;
int rc = -ENOMEM;
- struct ip6fl_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
+ struct ip6fl_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL);
if (!s)
goto out;
@@ -674,7 +673,6 @@ static int ip6fl_seq_open(struct inode *
seq = file->private_data;
seq->private = s;
- memset(s, 0, sizeof(*s));
out:
return rc;
out_kfree:
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 3c7b324..028b636 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -428,11 +428,10 @@ static int ipcomp6_init_state(struct xfr
goto out;
err = -ENOMEM;
- ipcd = kmalloc(sizeof(*ipcd), GFP_KERNEL);
+ ipcd = kzalloc(sizeof(*ipcd), GFP_KERNEL);
if (!ipcd)
goto out;
- memset(ipcd, 0, sizeof(*ipcd));
x->props.header_len = 0;
if (x->props.mode)
x->props.header_len += sizeof(struct ipv6hdr);
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 807c021..6e871af 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -767,10 +767,10 @@ static void mld_add_delrec(struct inet6_
* for deleted items allows change reports to use common code with
* non-deleted or query-response MCA's.
*/
- pmc = kmalloc(sizeof(*pmc), GFP_ATOMIC);
+ pmc = kzalloc(sizeof(*pmc), GFP_ATOMIC);
if (!pmc)
return;
- memset(pmc, 0, sizeof(*pmc));
+
spin_lock_bh(&im->mca_lock);
spin_lock_init(&pmc->mca_lock);
pmc->idev = im->idev;
@@ -893,7 +893,7 @@ int ipv6_dev_mc_inc(struct net_device *d
* not found: create a new one.
*/
- mc = kmalloc(sizeof(struct ifmcaddr6), GFP_ATOMIC);
+ mc = kzalloc(sizeof(struct ifmcaddr6), GFP_ATOMIC);
if (mc == NULL) {
write_unlock_bh(&idev->lock);
@@ -901,7 +901,6 @@ int ipv6_dev_mc_inc(struct net_device *d
return -ENOMEM;
}
- memset(mc, 0, sizeof(struct ifmcaddr6));
init_timer(&mc->mca_timer);
mc->mca_timer.function = igmp6_timer_handler;
mc->mca_timer.data = (unsigned long) mc;
@@ -1934,10 +1933,10 @@ static int ip6_mc_add1_src(struct ifmcad
psf_prev = psf;
}
if (!psf) {
- psf = kmalloc(sizeof(*psf), GFP_ATOMIC);
+ psf = kzalloc(sizeof(*psf), GFP_ATOMIC);
if (!psf)
return -ENOBUFS;
- memset(psf, 0, sizeof(*psf));
+
psf->sf_addr = *psfsrc;
if (psf_prev) {
psf_prev->sf_next = psf;
@@ -2431,7 +2430,7 @@ static int igmp6_mc_seq_open(struct inod
{
struct seq_file *seq;
int rc = -ENOMEM;
- struct igmp6_mc_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
+ struct igmp6_mc_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL);
if (!s)
goto out;
@@ -2442,7 +2441,6 @@ static int igmp6_mc_seq_open(struct inod
seq = file->private_data;
seq->private = s;
- memset(s, 0, sizeof(*s));
out:
return rc;
out_kfree:
@@ -2606,7 +2604,7 @@ static int igmp6_mcf_seq_open(struct ino
{
struct seq_file *seq;
int rc = -ENOMEM;
- struct igmp6_mcf_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
+ struct igmp6_mcf_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL);
if (!s)
goto out;
@@ -2617,7 +2615,6 @@ static int igmp6_mcf_seq_open(struct ino
seq = file->private_data;
seq->private = s;
- memset(s, 0, sizeof(*s));
out:
return rc;
out_kfree:
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 0f63078..fa1ce0a 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -1198,7 +1198,7 @@ static int raw6_seq_open(struct inode *i
{
struct seq_file *seq;
int rc = -ENOMEM;
- struct raw6_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
+ struct raw6_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL);
if (!s)
goto out;
rc = seq_open(file, &raw6_seq_ops);
@@ -1206,7 +1206,6 @@ static int raw6_seq_open(struct inode *i
goto out_kfree;
seq = file->private_data;
seq->private = s;
- memset(s, 0, sizeof(*s));
out:
return rc;
out_kfree:
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 074c49f..abcc7b2 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1877,11 +1877,10 @@ int inet6_dump_fib(struct sk_buff *skb,
/*
* 2. allocate and initialize walker.
*/
- w = kmalloc(sizeof(*w), GFP_ATOMIC);
+ w = kzalloc(sizeof(*w), GFP_ATOMIC);
if (w == NULL)
return -ENOMEM;
RT6_TRACE("dump<%p", w);
- memset(w, 0, sizeof(*w));
w->root = &ip6_routing_table;
w->func = fib6_dump_node;
w->args = &arg;
^ permalink raw reply related
* [PATCH] IPv6: Cleanup of net/ipv6/reassambly.c
From: Ingo Oeser @ 2006-03-11 23:49 UTC (permalink / raw)
To: YOSHIFUJI Hideaki / 吉藤英明
Cc: David S. Miller, netdev, linux-kernel
From: Ingo Oeser <ioe-lkml@rameria.de>
Two minor cleanups:
1. Using kzalloc() in fraq_alloc_queue()
saves the memset() in ipv6_frag_create().
2. Invert sense of if-statements to streamline code.
Inverts the comment, too.
Signed-off-by: Ingo Oeser <ioe-lkml@rameria.de>
---
Hi,
I first did the kzalloc cleanup, but then decided,
that I can do this change, too. If you consider it worse,
please tell me and I'll just do the kzalloc() one.
Regards
Ingo Oeser
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 15e1456..6d8c9bb 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -203,7 +203,7 @@ static inline void frag_free_queue(struc
static inline struct frag_queue *frag_alloc_queue(void)
{
- struct frag_queue *fq = kmalloc(sizeof(struct frag_queue), GFP_ATOMIC);
+ struct frag_queue *fq = kzalloc(sizeof(struct frag_queue), GFP_ATOMIC);
if(!fq)
return NULL;
@@ -288,6 +288,7 @@ static void ip6_evictor(void)
static void ip6_frag_expire(unsigned long data)
{
struct frag_queue *fq = (struct frag_queue *) data;
+ struct net_device *dev;
spin_lock(&fq->lock);
@@ -299,22 +300,22 @@ static void ip6_frag_expire(unsigned lon
IP6_INC_STATS_BH(IPSTATS_MIB_REASMTIMEOUT);
IP6_INC_STATS_BH(IPSTATS_MIB_REASMFAILS);
- /* Send error only if the first segment arrived. */
- if (fq->last_in&FIRST_IN && fq->fragments) {
- struct net_device *dev = dev_get_by_index(fq->iif);
-
- /*
- But use as source device on which LAST ARRIVED
- segment was received. And do not use fq->dev
- pointer directly, device might already disappeared.
- */
- if (dev) {
- fq->fragments->dev = dev;
- icmpv6_send(fq->fragments, ICMPV6_TIME_EXCEED, ICMPV6_EXC_FRAGTIME, 0,
- dev);
- dev_put(dev);
- }
- }
+ /* Don't send error if the first segment did not arrive. */
+ if (!(fq->last_in&FIRST_IN) || !fq->fragments)
+ goto out;
+
+ dev = dev_get_by_index(fq->iif);
+ if (!dev)
+ goto out;
+
+ /*
+ But use as source device on which LAST ARRIVED
+ segment was received. And do not use fq->dev
+ pointer directly, device might already disappeared.
+ */
+ fq->fragments->dev = dev;
+ icmpv6_send(fq->fragments, ICMPV6_TIME_EXCEED, ICMPV6_EXC_FRAGTIME, 0, dev);
+ dev_put(dev);
out:
spin_unlock(&fq->lock);
fq_put(fq, NULL);
@@ -368,8 +369,6 @@ ip6_frag_create(unsigned int hash, u32 i
if ((fq = frag_alloc_queue()) == NULL)
goto oom;
- memset(fq, 0, sizeof(struct frag_queue));
-
fq->id = id;
ipv6_addr_copy(&fq->saddr, src);
ipv6_addr_copy(&fq->daddr, dst);
^ permalink raw reply related
* Re: Linux v2.6.16-rc6
From: Michal Piotrowski @ 2006-03-12 1:51 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Linux Kernel Mailing List, netdev
In-Reply-To: <Pine.LNX.4.64.0603111551330.18022@g5.osdl.org>
Hi,
On 12/03/06, Linus Torvalds <torvalds@osdl.org> wrote:
>
> Ok, we're getting closer, although the 2.6.16 release certainly seems to
> drag out more than it should have.
>
I have noticed this warnings
TCP: Treason uncloaked! Peer 82.113.55.2:11759/50967 shrinks window
148470938:148470943. Repaired.
TCP: Treason uncloaked! Peer 82.113.55.2:11759/50967 shrinks window
148470938:148470943. Repaired.
TCP: Treason uncloaked! Peer 82.113.55.2:11759/59768 shrinks window
1124211698:1124211703. Repaired.
TCP: Treason uncloaked! Peer 82.113.55.2:11759/59768 shrinks window
1124211698:1124211703. Repaired.
It maybe problem with ktorrent.
Here is config http://www.stardust.webpages.pl/files/linux/2.6.16-rc6/config
Here is dmesg http://www.stardust.webpages.pl/files/linux/2.6.16-rc6/dmesg
Regards,
Michal
--
Michal K. K. Piotrowski
LTG - Linux Testers Group
(http://www.stardust.webpages.pl/ltg/wiki/)
^ permalink raw reply
* Re: Linux v2.6.16-rc6
From: David S. Miller @ 2006-03-12 2:39 UTC (permalink / raw)
To: michal.k.k.piotrowski; +Cc: torvalds, linux-kernel, netdev
In-Reply-To: <6bffcb0e0603111751i1ed30794s@mail.gmail.com>
From: "Michal Piotrowski" <michal.k.k.piotrowski@gmail.com>
Date: Sun, 12 Mar 2006 02:51:40 +0100
> I have noticed this warnings
> TCP: Treason uncloaked! Peer 82.113.55.2:11759/50967 shrinks window
> 148470938:148470943. Repaired.
> TCP: Treason uncloaked! Peer 82.113.55.2:11759/50967 shrinks window
> 148470938:148470943. Repaired.
> TCP: Treason uncloaked! Peer 82.113.55.2:11759/59768 shrinks window
> 1124211698:1124211703. Repaired.
> TCP: Treason uncloaked! Peer 82.113.55.2:11759/59768 shrinks window
> 1124211698:1124211703. Repaired.
>
> It maybe problem with ktorrent.
It is a problem with the remote TCP implementation, it is
illegally advertising a smaller window that it previously
did.
^ permalink raw reply
* Re: [PATCH] IPv6: Cleanup of net/ipv6/reassambly.c
From: Ingo Oeser @ 2006-03-12 7:17 UTC (permalink / raw)
To: YOSHIFUJI Hideaki / 吉藤英明
Cc: David S. Miller, netdev, linux-kernel
In-Reply-To: <200603120049.49294.ioe-lkml@rameria.de>
Hi,
On Sunday, 12. March 2006 00:49, Ingo Oeser wrote:
> From: Ingo Oeser <ioe-lkml@rameria.de>
>
> Two minor cleanups:
>
> 1. Using kzalloc() in fraq_alloc_queue()
> saves the memset() in ipv6_frag_create().
>
> 2. Invert sense of if-statements to streamline code.
> Inverts the comment, too.
>
These are against net-2.6.17 of course.
I also compile tested this and my other kzalloc() changes.
Forgot to mention this yesterday...
Regards
Ingo Oeser
^ permalink raw reply
* Re: Linux v2.6.16-rc6
From: Willy Tarreau @ 2006-03-12 8:35 UTC (permalink / raw)
To: David S. Miller
Cc: michal.k.k.piotrowski, torvalds, linux-kernel, netdev, herbert
In-Reply-To: <20060311.183904.71244086.davem@davemloft.net>
On Sat, Mar 11, 2006 at 06:39:04PM -0800, David S. Miller wrote:
> From: "Michal Piotrowski" <michal.k.k.piotrowski@gmail.com>
> Date: Sun, 12 Mar 2006 02:51:40 +0100
>
> > I have noticed this warnings
> > TCP: Treason uncloaked! Peer 82.113.55.2:11759/50967 shrinks window
> > 148470938:148470943. Repaired.
> > TCP: Treason uncloaked! Peer 82.113.55.2:11759/50967 shrinks window
> > 148470938:148470943. Repaired.
> > TCP: Treason uncloaked! Peer 82.113.55.2:11759/59768 shrinks window
> > 1124211698:1124211703. Repaired.
> > TCP: Treason uncloaked! Peer 82.113.55.2:11759/59768 shrinks window
> > 1124211698:1124211703. Repaired.
> >
> > It maybe problem with ktorrent.
>
> It is a problem with the remote TCP implementation, it is
> illegally advertising a smaller window that it previously
> did.
on 2005/10/27, Herbert Xu provided a patch merged in 2.6.14 to fix some
erroneous occurences of this message (some of them appeared with Linux
on the other side). It would be interesting to know whether the peer
above is Linux or not, because it might be possible that Herbert's fix
needs to be applied to other places ?
Here comes his patch with his interesting analysis for reference, in
case it might give ideas to anybody.
Cheers,
Willy
---
From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Thu, 27 Oct 2005 08:47:46 +0000 (+1000)
Subject: [TCP]: Clear stale pred_flags when snd_wnd changes
X-Git-Tag: v2.6.14
X-Git-Url: http://kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=2ad41065d9fe518759b695fc2640cf9c07261dd2
[TCP]: Clear stale pred_flags when snd_wnd changes
This bug is responsible for causing the infamous "Treason uncloaked"
messages that's been popping up everywhere since the printk was added.
It has usually been blamed on foreign operating systems. However,
some of those reports implicate Linux as both systems are running
Linux or the TCP connection is going across the loopback interface.
In fact, there really is a bug in the Linux TCP header prediction code
that's been there since at least 2.1.8. This bug was tracked down with
help from Dale Blount.
The effect of this bug ranges from harmless "Treason uncloaked"
messages to hung/aborted TCP connections. The details of the bug
and fix is as follows.
When snd_wnd is updated, we only update pred_flags if
tcp_fast_path_check succeeds. When it fails (for example,
when our rcvbuf is used up), we will leave pred_flags with
an out-of-date snd_wnd value.
When the out-of-date pred_flags happens to match the next incoming
packet we will again hit the fast path and use the current snd_wnd
which will be wrong.
In the case of the treason messages, it just happens that the snd_wnd
cached in pred_flags is zero while tp->snd_wnd is non-zero. Therefore
when a zero-window packet comes in we incorrectly conclude that the
window is non-zero.
In fact if the peer continues to send us zero-window pure ACKs we
will continue making the same mistake. It's only when the peer
transmits a zero-window packet with data attached that we get a
chance to snap out of it. This is what triggers the treason
message at the next retransmit timeout.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
---
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -2239,6 +2239,7 @@ static int tcp_ack_update_window(struct
/* Note, it is the only place, where
* fast path is recovered for sending TCP.
*/
+ tp->pred_flags = 0;
tcp_fast_path_check(sk, tp);
if (nwin > tp->max_window) {
----
^ permalink raw reply
* Re: [PATCH 2/8] [I/OAT] Driver for the Intel(R) I/OAT DMA engine
From: Evgeniy Polyakov @ 2006-03-12 10:47 UTC (permalink / raw)
To: Leech, Christopher; +Cc: linux-kernel, netdev
In-Reply-To: <E3A930D59AFC3345AEBA35189102A8A6060E15E7@orsmsx404.amr.corp.intel.com>
On Fri, Mar 10, 2006 at 06:29:46PM -0800, Leech, Christopher (christopher.leech@intel.com) wrote:
> From: Chris Leech [mailto:christopher.leech@intel.com]
> Sent: Friday, March 10, 2006 6:29 PM
> To:
> Subject: [PATCH 2/8] [I/OAT] Driver for the Intel(R) I/OAT DMA engine
>
>
> Adds a new ioatdma driver
enumerate_dma_channels() is still broken, if it can not fail add NOFAIL
gfp flag.
And you play tricky games with common_node/device_node of struct
dma_chan - one of that lists is never protected, while other is called
under RCU and other locks (btw, why does insertion use RCU and deletion
in dma_async_device_unregister() does not?).
struct ioat_dma_chan - is it somewhere freed?
--
Evgeniy Polyakov
^ permalink raw reply
* Re: [PATCH 2/8] [I/OAT] Driver for the Intel(R) I/OAT DMA engine
From: Andrew Morton @ 2006-03-12 11:04 UTC (permalink / raw)
To: Evgeniy Polyakov; +Cc: christopher.leech, linux-kernel, netdev
In-Reply-To: <20060312104728.GA25301@2ka.mipt.ru>
Evgeniy Polyakov <johnpol@2ka.mipt.ru> wrote:
>
> On Fri, Mar 10, 2006 at 06:29:46PM -0800, Leech, Christopher (christopher.leech@intel.com) wrote:
> > From: Chris Leech [mailto:christopher.leech@intel.com]
> > Sent: Friday, March 10, 2006 6:29 PM
> > To:
> > Subject: [PATCH 2/8] [I/OAT] Driver for the Intel(R) I/OAT DMA engine
> >
> >
> > Adds a new ioatdma driver
>
> enumerate_dma_channels() is still broken, if it can not fail add NOFAIL
> gfp flag.
The __GFP_NOFAIL flag is there to mark lame-and-buggy-code which doesn't
know how to handle ENOMEM. I went through the kernel, found all the
retry-until-it-works loops and consolidated their behaviour in the page
allocator instead.
Really we should fix them all up. Adding new users of __GFP_NOFAIL
would not be good.
^ permalink raw reply
* Re: Linux v2.6.16-rc6
From: Michal Piotrowski @ 2006-03-12 12:04 UTC (permalink / raw)
To: David S. Miller; +Cc: torvalds, linux-kernel, netdev
In-Reply-To: <20060311.183904.71244086.davem@davemloft.net>
Hi,
On 12/03/06, David S. Miller <davem@davemloft.net> wrote:
> From: "Michal Piotrowski" <michal.k.k.piotrowski@gmail.com>
> Date: Sun, 12 Mar 2006 02:51:40 +0100
>
> > I have noticed this warnings
> > TCP: Treason uncloaked! Peer 82.113.55.2:11759/50967 shrinks window
> > 148470938:148470943. Repaired.
> > TCP: Treason uncloaked! Peer 82.113.55.2:11759/50967 shrinks window
> > 148470938:148470943. Repaired.
> > TCP: Treason uncloaked! Peer 82.113.55.2:11759/59768 shrinks window
> > 1124211698:1124211703. Repaired.
> > TCP: Treason uncloaked! Peer 82.113.55.2:11759/59768 shrinks window
> > 1124211698:1124211703. Repaired.
> >
> > It maybe problem with ktorrent.
>
> It is a problem with the remote TCP implementation, it is
> illegally advertising a smaller window that it previously
> did.
>
Thanks for explanation.
Regards,
Michal
--
Michal K. K. Piotrowski
LTG - Linux Testers Group
(http://www.stardust.webpages.pl/ltg/wiki/)
^ permalink raw reply
* Re: [PATCH] Nearly complete kzalloc cleanup for net/ipv6
From: Patrick McHardy @ 2006-03-12 13:57 UTC (permalink / raw)
To: Ingo Oeser
Cc: YOSHIFUJI Hideaki / 吉藤英明,
David Miller, linux-kernel, netdev
In-Reply-To: <200603112136.43553.ioe-lkml@rameria.de>
Ingo Oeser wrote:
> From: Ingo Oeser <ioe-lkml@rameria.de>
>
> Stupidly use kzalloc() instead of kmalloc()/memset()
> everywhere where this is possible in net/ipv6/*.c .
>
> The netfilter part is NOT included, because Harald should see these, too.
Feel free to send netfilter patches to me.
^ permalink raw reply
* Re: 2.6.16-rc6-mm1
From: Benoit Boissinot @ 2006-03-12 15:55 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-kernel, jgarzik, netdev
In-Reply-To: <20060312031036.3a382581.akpm@osdl.org>
On Sun, Mar 12, 2006 at 03:10:36AM -0800, Andrew Morton wrote:
>
> ftp://ftp.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.16-rc6/2.6.16-rc6-mm1/
>
>
drivers/net/tg3.c:8065: warning: type qualifiers ignored on function return type
Signed-off-by: Benoit Boissinot <benoit.boissinot@ens-lyon.fr>
Index: linux/drivers/net/tg3.c
===================================================================
--- linux.orig/drivers/net/tg3.c
+++ linux/drivers/net/tg3.c
@@ -8061,7 +8061,7 @@ static int tg3_test_link(struct tg3 *tp)
}
/* Only test the commonly used registers */
-static const int tg3_test_registers(struct tg3 *tp)
+static int tg3_test_registers(struct tg3 *tp)
{
int i, is_5705;
u32 offset, read_mask, write_mask, val, save_val, read_val;
--
powered by bash/screen/(urxvt/fvwm|linux-console)/gentoo/gnu/linux OS
^ permalink raw reply
* [patch 0/4] natsemi: Aculab E1/T1 PMXc Carrier Card support
From: Mark Brown @ 2006-03-12 19:22 UTC (permalink / raw)
To: Tim Hockin, Jeff Garzik; +Cc: netdev, linux-kernel
This patch series against the upstream branch of netdev-2.6 adds support
for these boards to the natsemi driver. It implements some new
functionality required by the boards and enables the appropriate
settings when such a board is detected.
--
"You grabbed my hand and we fell into it, like a daydream - or a fever."
^ permalink raw reply
* [patch 1/4] natsemi: Add support for using MII port with no PHY
From: Mark Brown @ 2006-03-12 19:23 UTC (permalink / raw)
To: Tim Hockin, Jeff Garzik; +Cc: netdev, linux-kernel
In-Reply-To: <20060312192259.929734000@mercator.sirena.org.uk>
[-- Attachment #1: natsemi-ignore-phy.patch --]
[-- Type: text/plain, Size: 6510 bytes --]
This patch provides a module option which configures the natsemi driver
to use the external MII port on the chip but ignore any PHYs that may be
attached to it. The link state will be left as it was when the driver
started and can be configured via ethtool. Any PHYs that are present
can be accessed via the MII ioctl()s.
This is useful for systems where the device is connected without a PHY
or where either information or actions outside the scope of the driver
are required in order to use the PHYs.
Signed-Off-By: Mark Brown <broonie@sirena.org.uk>
Index: natsemi-queue/drivers/net/natsemi.c
===================================================================
--- natsemi-queue.orig/drivers/net/natsemi.c 2006-02-25 13:38:34.000000000 +0000
+++ natsemi-queue/drivers/net/natsemi.c 2006-02-25 13:50:51.000000000 +0000
@@ -259,7 +259,7 @@ MODULE_PARM_DESC(debug, "DP8381x default
MODULE_PARM_DESC(rx_copybreak,
"DP8381x copy breakpoint for copy-only-tiny-frames");
MODULE_PARM_DESC(options,
- "DP8381x: Bits 0-3: media type, bit 17: full duplex");
+ "DP8381x: Bits 0-3: media type, bit 17: full duplex, bit 18: ignore PHY");
MODULE_PARM_DESC(full_duplex, "DP8381x full duplex setting(s) (1)");
/*
@@ -690,6 +690,8 @@ struct netdev_private {
u32 intr_status;
/* Do not touch the nic registers */
int hands_off;
+ /* Don't pay attention to the reported link state. */
+ int ignore_phy;
/* external phy that is used: only valid if dev->if_port != PORT_TP */
int mii;
int phy_addr_external;
@@ -891,7 +893,19 @@ static int __devinit natsemi_probe1 (str
np->hands_off = 0;
np->intr_status = 0;
+ option = find_cnt < MAX_UNITS ? options[find_cnt] : 0;
+ if (dev->mem_start)
+ option = dev->mem_start;
+
+ /* Ignore the PHY status? */
+ if (option & 0x400) {
+ np->ignore_phy = 1;
+ } else {
+ np->ignore_phy = 0;
+ }
+
/* Initial port:
+ * - If configured to ignore the PHY set up for external.
* - If the nic was configured to use an external phy and if find_mii
* finds a phy: use external port, first phy that replies.
* - Otherwise: internal port.
@@ -899,7 +913,7 @@ static int __devinit natsemi_probe1 (str
* The address would be used to access a phy over the mii bus, but
* the internal phy is accessed through mapped registers.
*/
- if (readl(ioaddr + ChipConfig) & CfgExtPhy)
+ if (np->ignore_phy || readl(ioaddr + ChipConfig) & CfgExtPhy)
dev->if_port = PORT_MII;
else
dev->if_port = PORT_TP;
@@ -909,7 +923,9 @@ static int __devinit natsemi_probe1 (str
if (dev->if_port != PORT_TP) {
np->phy_addr_external = find_mii(dev);
- if (np->phy_addr_external == PHY_ADDR_NONE) {
+ /* If we're ignoring the PHY it doesn't matter if we can't
+ * find one. */
+ if (!np->ignore_phy && np->phy_addr_external == PHY_ADDR_NONE) {
dev->if_port = PORT_TP;
np->phy_addr_external = PHY_ADDR_INTERNAL;
}
@@ -917,10 +933,6 @@ static int __devinit natsemi_probe1 (str
np->phy_addr_external = PHY_ADDR_INTERNAL;
}
- option = find_cnt < MAX_UNITS ? options[find_cnt] : 0;
- if (dev->mem_start)
- option = dev->mem_start;
-
/* The lower four bits are the media type. */
if (option) {
if (option & 0x200)
@@ -954,7 +966,10 @@ static int __devinit natsemi_probe1 (str
if (mtu)
dev->mtu = mtu;
- netif_carrier_off(dev);
+ if (np->ignore_phy)
+ netif_carrier_on(dev);
+ else
+ netif_carrier_off(dev);
/* get the initial settings from hardware */
tmp = mdio_read(dev, MII_BMCR);
@@ -1002,6 +1017,8 @@ static int __devinit natsemi_probe1 (str
printk("%02x, IRQ %d", dev->dev_addr[i], irq);
if (dev->if_port == PORT_TP)
printk(", port TP.\n");
+ else if (np->ignore_phy)
+ printk(", port MII, ignoring PHY\n");
else
printk(", port MII, phy ad %d.\n", np->phy_addr_external);
}
@@ -1682,42 +1699,44 @@ static void check_link(struct net_device
{
struct netdev_private *np = netdev_priv(dev);
void __iomem * ioaddr = ns_ioaddr(dev);
- int duplex;
+ int duplex = np->full_duplex;
u16 bmsr;
-
- /* The link status field is latched: it remains low after a temporary
- * link failure until it's read. We need the current link status,
- * thus read twice.
- */
- mdio_read(dev, MII_BMSR);
- bmsr = mdio_read(dev, MII_BMSR);
- if (!(bmsr & BMSR_LSTATUS)) {
- if (netif_carrier_ok(dev)) {
+ /* If we're not paying attention to the PHY status then don't check. */
+ if (!np->ignore_phy) {
+ /* The link status field is latched: it remains low
+ * after a temporary link failure until it's read. We
+ * need the current link status, thus read twice.
+ */
+ mdio_read(dev, MII_BMSR);
+ bmsr = mdio_read(dev, MII_BMSR);
+
+ if (!(bmsr & BMSR_LSTATUS)) {
+ if (netif_carrier_ok(dev)) {
+ if (netif_msg_link(np))
+ printk(KERN_NOTICE "%s: link down.\n",
+ dev->name);
+ netif_carrier_off(dev);
+ undo_cable_magic(dev);
+ }
+ return;
+ }
+ if (!netif_carrier_ok(dev)) {
if (netif_msg_link(np))
- printk(KERN_NOTICE "%s: link down.\n",
- dev->name);
- netif_carrier_off(dev);
- undo_cable_magic(dev);
+ printk(KERN_NOTICE "%s: link up.\n", dev->name);
+ netif_carrier_on(dev);
+ do_cable_magic(dev);
}
- return;
- }
- if (!netif_carrier_ok(dev)) {
- if (netif_msg_link(np))
- printk(KERN_NOTICE "%s: link up.\n", dev->name);
- netif_carrier_on(dev);
- do_cable_magic(dev);
- }
- duplex = np->full_duplex;
- if (!duplex) {
- if (bmsr & BMSR_ANEGCOMPLETE) {
- int tmp = mii_nway_result(
- np->advertising & mdio_read(dev, MII_LPA));
- if (tmp == LPA_100FULL || tmp == LPA_10FULL)
+ if (!duplex) {
+ if (bmsr & BMSR_ANEGCOMPLETE) {
+ int tmp = mii_nway_result(
+ np->advertising & mdio_read(dev, MII_LPA));
+ if (tmp == LPA_100FULL || tmp == LPA_10FULL)
+ duplex = 1;
+ } else if (mdio_read(dev, MII_BMCR) & BMCR_FULLDPLX)
duplex = 1;
- } else if (mdio_read(dev, MII_BMCR) & BMCR_FULLDPLX)
- duplex = 1;
+ }
}
/* if duplex is set then bit 28 must be set, too */
@@ -2927,6 +2946,16 @@ static int netdev_set_ecmd(struct net_de
}
/*
+ * If we're ignoring the PHY then autoneg and the internal
+ * transciever are really not going to work so don't let the
+ * user select them.
+ */
+ if (np->ignore_phy && (ecmd->autoneg == AUTONEG_ENABLE ||
+ ecmd->port == PORT_INTERNAL)) {
+ return -EINVAL;
+ }
+
+ /*
* maxtxpkt, maxrxpkt: ignored for now.
*
* transceiver:
--
"You grabbed my hand and we fell into it, like a daydream - or a fever."
^ permalink raw reply
* [patch 2/4] natsemi: Support oversized EEPROMs
From: Mark Brown @ 2006-03-12 19:23 UTC (permalink / raw)
To: Tim Hockin, Jeff Garzik; +Cc: netdev, linux-kernel
In-Reply-To: <20060312192259.929734000@mercator.sirena.org.uk>
[-- Attachment #1: natsemi-variable-eeprom-size.patch --]
[-- Type: text/plain, Size: 2871 bytes --]
The natsemi chip can have a larger EEPROM attached than it itself uses
for configuration. This patch adds support for user space access
to such an EEPROM.
Signed-off-by: Mark Brown <broonie@sirena.org.uk>
Index: natsemi-queue/drivers/net/natsemi.c
===================================================================
--- natsemi-queue.orig/drivers/net/natsemi.c 2006-02-25 17:40:15.000000000 +0000
+++ natsemi-queue/drivers/net/natsemi.c 2006-02-25 17:40:39.000000000 +0000
@@ -226,7 +226,7 @@ static int full_duplex[MAX_UNITS];
NATSEMI_PG1_NREGS)
#define NATSEMI_REGS_VER 1 /* v1 added RFDR registers */
#define NATSEMI_REGS_SIZE (NATSEMI_NREGS * sizeof(u32))
-#define NATSEMI_EEPROM_SIZE 24 /* 12 16-bit values */
+#define NATSEMI_DEF_EEPROM_SIZE 24 /* 12 16-bit values */
/* Buffer sizes:
* The nic writes 32-bit values, even if the upper bytes of
@@ -716,6 +716,8 @@ struct netdev_private {
unsigned int iosize;
spinlock_t lock;
u32 msg_enable;
+ /* EEPROM data */
+ int eeprom_size;
};
static void move_int_phy(struct net_device *dev, int addr);
@@ -892,6 +894,7 @@ static int __devinit natsemi_probe1 (str
np->msg_enable = (debug >= 0) ? (1<<debug)-1 : NATSEMI_DEF_MSG;
np->hands_off = 0;
np->intr_status = 0;
+ np->eeprom_size = NATSEMI_DEF_EEPROM_SIZE;
option = find_cnt < MAX_UNITS ? options[find_cnt] : 0;
if (dev->mem_start)
@@ -2601,7 +2604,8 @@ static int get_regs_len(struct net_devic
static int get_eeprom_len(struct net_device *dev)
{
- return NATSEMI_EEPROM_SIZE;
+ struct netdev_private *np = netdev_priv(dev);
+ return np->eeprom_size;
}
static int get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
@@ -2688,15 +2692,20 @@ static u32 get_link(struct net_device *d
static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data)
{
struct netdev_private *np = netdev_priv(dev);
- u8 eebuf[NATSEMI_EEPROM_SIZE];
+ u8 *eebuf;
int res;
+ eebuf = kmalloc(np->eeprom_size, GFP_KERNEL);
+ if (!eebuf)
+ return -ENOMEM;
+
eeprom->magic = PCI_VENDOR_ID_NS | (PCI_DEVICE_ID_NS_83815<<16);
spin_lock_irq(&np->lock);
res = netdev_get_eeprom(dev, eebuf);
spin_unlock_irq(&np->lock);
if (!res)
memcpy(data, eebuf+eeprom->offset, eeprom->len);
+ kfree(eebuf);
return res;
}
@@ -3062,9 +3071,10 @@ static int netdev_get_eeprom(struct net_
int i;
u16 *ebuf = (u16 *)buf;
void __iomem * ioaddr = ns_ioaddr(dev);
+ struct netdev_private *np = netdev_priv(dev);
/* eeprom_read reads 16 bits, and indexes by 16 bits */
- for (i = 0; i < NATSEMI_EEPROM_SIZE/2; i++) {
+ for (i = 0; i < np->eeprom_size/2; i++) {
ebuf[i] = eeprom_read(ioaddr, i);
/* The EEPROM itself stores data bit-swapped, but eeprom_read
* reads it back "sanely". So we swap it back here in order to
--
"You grabbed my hand and we fell into it, like a daydream - or a fever."
^ permalink raw reply
* [patch 3/4] Add a PCI vendor ID definition for Aculab
From: Mark Brown @ 2006-03-12 19:23 UTC (permalink / raw)
To: Tim Hockin, Jeff Garzik; +Cc: netdev, linux-kernel
In-Reply-To: <20060312192259.929734000@mercator.sirena.org.uk>
[-- Attachment #1: pci-vendor-aculab.patch --]
[-- Type: text/plain, Size: 735 bytes --]
Add a vendor ID definition for Aculab.
Signed-Off-By: Mark Brown <broonie@sirena.org.uk>
Index: e1000-queue/include/linux/pci_ids.h
===================================================================
--- e1000-queue.orig/include/linux/pci_ids.h 2006-02-25 12:50:12.000000000 +0000
+++ e1000-queue/include/linux/pci_ids.h 2006-02-25 12:51:51.000000000 +0000
@@ -1572,6 +1572,8 @@
#define PCI_VENDOR_ID_NVIDIA_SGS 0x12d2
#define PCI_DEVICE_ID_NVIDIA_SGS_RIVA128 0x0018
+#define PCI_VENDOR_ID_ACULAB 0x12d9
+
#define PCI_SUBVENDOR_ID_CHASE_PCIFAST 0x12E0
#define PCI_SUBDEVICE_ID_CHASE_PCIFAST4 0x0031
#define PCI_SUBDEVICE_ID_CHASE_PCIFAST8 0x0021
--
"You grabbed my hand and we fell into it, like a daydream - or a fever."
^ permalink raw reply
* [patch 4/4] natsemi: Add quirks for Aculab E1/T1 PMXc cPCI carrier cards
From: Mark Brown @ 2006-03-12 19:23 UTC (permalink / raw)
To: Tim Hockin, Jeff Garzik; +Cc: netdev, linux-kernel
In-Reply-To: <20060312192259.929734000@mercator.sirena.org.uk>
[-- Attachment #1: natsemi-aculab-cpci-carrier.patch --]
[-- Type: text/plain, Size: 6563 bytes --]
Aculab E1/T1 PMXc cPCI carrier card cards present a natsemi on the cPCI
bus wired up in a non-standard fashion. This patch provides support in
the natsemi driver for these cards by implementing a quirk mechanism and
using that to configure appropriate settings for the card: forcing 100M
full duplex, having a large EEPROM and using the MII port while ignoring
PHYs.
Signed-off-by: Mark Brown <broonie@sirena.org.uk>
Index: natsemi-queue/drivers/net/natsemi.c
===================================================================
--- natsemi-queue.orig/drivers/net/natsemi.c 2006-02-25 17:41:59.000000000 +0000
+++ natsemi-queue/drivers/net/natsemi.c 2006-03-08 21:44:12.000000000 +0000
@@ -226,7 +226,6 @@ static int full_duplex[MAX_UNITS];
NATSEMI_PG1_NREGS)
#define NATSEMI_REGS_VER 1 /* v1 added RFDR registers */
#define NATSEMI_REGS_SIZE (NATSEMI_NREGS * sizeof(u32))
-#define NATSEMI_DEF_EEPROM_SIZE 24 /* 12 16-bit values */
/* Buffer sizes:
* The nic writes 32-bit values, even if the upper bytes of
@@ -344,12 +343,14 @@ None characterised.
-enum pcistuff {
+enum natsemi_quirks {
PCI_USES_IO = 0x01,
PCI_USES_MEM = 0x02,
PCI_USES_MASTER = 0x04,
PCI_ADDR0 = 0x08,
PCI_ADDR1 = 0x10,
+ MEDIA_FORCE_100FD = 0x20,
+ MEDIA_IGNORE_PHY = 0x40,
};
/* MMIO operations required */
@@ -367,17 +368,21 @@ enum pcistuff {
#define MII_FX_SEL 0x0001 /* 100BASE-FX (fiber) */
#define MII_EN_SCRM 0x0004 /* enable scrambler (tp) */
-
/* array of board data directly indexed by pci_tbl[x].driver_data */
static const struct {
const char *name;
unsigned long flags;
+ int quirks;
+ int eeprom_size;
} natsemi_pci_info[] __devinitdata = {
- { "NatSemi DP8381[56]", PCI_IOTYPE },
+ { "NatSemi DP8381[56]", PCI_IOTYPE, 0, 24 },
+ { "Aculab E1/T1 PMXc cPCI carrier card", PCI_IOTYPE,
+ MEDIA_FORCE_100FD | MEDIA_IGNORE_PHY, 128 },
};
static struct pci_device_id natsemi_pci_tbl[] = {
- { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_83815, PCI_ANY_ID, PCI_ANY_ID, },
+ { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_83815, PCI_VENDOR_ID_ACULAB, PCI_SUBDEVICE_ID_ACULAB_174, 0, 0, 1 },
+ { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_83815, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, natsemi_pci_tbl);
@@ -815,6 +820,39 @@ static void move_int_phy(struct net_devi
udelay(1);
}
+static void __devinit natsemi_init_media (struct net_device *dev)
+{
+ struct netdev_private *np = netdev_priv(dev);
+ u32 tmp;
+
+ tmp = mdio_read(dev, MII_BMCR);
+ np->speed = (tmp & BMCR_SPEED100)? SPEED_100 : SPEED_10;
+ np->duplex = (tmp & BMCR_FULLDPLX)? DUPLEX_FULL : DUPLEX_HALF;
+ np->autoneg = (tmp & BMCR_ANENABLE)? AUTONEG_ENABLE: AUTONEG_DISABLE;
+ np->advertising= mdio_read(dev, MII_ADVERTISE);
+
+ if ((np->advertising & ADVERTISE_ALL) != ADVERTISE_ALL
+ && netif_msg_probe(np)) {
+ printk(KERN_INFO "natsemi %s: Transceiver default autonegotiation %s "
+ "10%s %s duplex.\n",
+ pci_name(np->pci_dev),
+ (mdio_read(dev, MII_BMCR) & BMCR_ANENABLE)?
+ "enabled, advertise" : "disabled, force",
+ (np->advertising &
+ (ADVERTISE_100FULL|ADVERTISE_100HALF))?
+ "0" : "",
+ (np->advertising &
+ (ADVERTISE_100FULL|ADVERTISE_10FULL))?
+ "full" : "half");
+ }
+ if (netif_msg_probe(np))
+ printk(KERN_INFO
+ "natsemi %s: Transceiver status %#04x advertising %#04x.\n",
+ pci_name(np->pci_dev), mdio_read(dev, MII_BMSR),
+ np->advertising);
+
+}
+
static int __devinit natsemi_probe1 (struct pci_dev *pdev,
const struct pci_device_id *ent)
{
@@ -894,17 +932,21 @@ static int __devinit natsemi_probe1 (str
np->msg_enable = (debug >= 0) ? (1<<debug)-1 : NATSEMI_DEF_MSG;
np->hands_off = 0;
np->intr_status = 0;
- np->eeprom_size = NATSEMI_DEF_EEPROM_SIZE;
+ np->eeprom_size = natsemi_pci_info[chip_idx].eeprom_size;
option = find_cnt < MAX_UNITS ? options[find_cnt] : 0;
if (dev->mem_start)
option = dev->mem_start;
/* Ignore the PHY status? */
- if (option & 0x400) {
+ if (natsemi_pci_info[chip_idx].quirks & MEDIA_IGNORE_PHY) {
np->ignore_phy = 1;
} else {
- np->ignore_phy = 0;
+ if (option & 0x400) {
+ np->ignore_phy = 1;
+ } else {
+ np->ignore_phy = 0;
+ }
}
/* Initial port:
@@ -936,6 +978,12 @@ static int __devinit natsemi_probe1 (str
np->phy_addr_external = PHY_ADDR_INTERNAL;
}
+ /* Apply any speed quirks. */
+ if (natsemi_pci_info[chip_idx].quirks & MEDIA_FORCE_100FD) {
+ np->speed = 100;
+ np->duplex = 1;
+ }
+
/* The lower four bits are the media type. */
if (option) {
if (option & 0x200)
@@ -974,32 +1022,10 @@ static int __devinit natsemi_probe1 (str
else
netif_carrier_off(dev);
- /* get the initial settings from hardware */
- tmp = mdio_read(dev, MII_BMCR);
- np->speed = (tmp & BMCR_SPEED100)? SPEED_100 : SPEED_10;
- np->duplex = (tmp & BMCR_FULLDPLX)? DUPLEX_FULL : DUPLEX_HALF;
- np->autoneg = (tmp & BMCR_ANENABLE)? AUTONEG_ENABLE: AUTONEG_DISABLE;
- np->advertising= mdio_read(dev, MII_ADVERTISE);
-
- if ((np->advertising & ADVERTISE_ALL) != ADVERTISE_ALL
- && netif_msg_probe(np)) {
- printk(KERN_INFO "natsemi %s: Transceiver default autonegotiation %s "
- "10%s %s duplex.\n",
- pci_name(np->pci_dev),
- (mdio_read(dev, MII_BMCR) & BMCR_ANENABLE)?
- "enabled, advertise" : "disabled, force",
- (np->advertising &
- (ADVERTISE_100FULL|ADVERTISE_100HALF))?
- "0" : "",
- (np->advertising &
- (ADVERTISE_100FULL|ADVERTISE_10FULL))?
- "full" : "half");
- }
- if (netif_msg_probe(np))
- printk(KERN_INFO
- "natsemi %s: Transceiver status %#04x advertising %#04x.\n",
- pci_name(np->pci_dev), mdio_read(dev, MII_BMSR),
- np->advertising);
+ /* get the initial settings from hardware if we don't have any
+ * already */
+ if (!np->speed)
+ natsemi_init_media(dev);
/* save the silicon revision for later querying */
np->srr = readl(ioaddr + SiliconRev);
Index: natsemi-queue/include/linux/pci_ids.h
===================================================================
--- natsemi-queue.orig/include/linux/pci_ids.h 2006-02-25 19:19:55.000000000 +0000
+++ natsemi-queue/include/linux/pci_ids.h 2006-02-25 19:21:28.000000000 +0000
@@ -1573,6 +1573,7 @@
#define PCI_DEVICE_ID_NVIDIA_SGS_RIVA128 0x0018
#define PCI_VENDOR_ID_ACULAB 0x12d9
+#define PCI_SUBDEVICE_ID_ACULAB_174 0x000c
#define PCI_SUBVENDOR_ID_CHASE_PCIFAST 0x12E0
#define PCI_SUBDEVICE_ID_CHASE_PCIFAST4 0x0031
--
"You grabbed my hand and we fell into it, like a daydream - or a fever."
^ permalink raw reply
* Re: [patch 1/4] natsemi: Add support for using MII port with no PHY
From: thockin @ 2006-03-12 21:41 UTC (permalink / raw)
To: Mark Brown; +Cc: Jeff Garzik, netdev, linux-kernel
In-Reply-To: <20060312205303.869316000@mercator.sirena.org.uk>
On Sun, Mar 12, 2006 at 07:23:00PM +0000, Mark Brown wrote:
> This patch provides a module option which configures the natsemi driver
> to use the external MII port on the chip but ignore any PHYs that may be
> attached to it. The link state will be left as it was when the driver
> started and can be configured via ethtool. Any PHYs that are present
> can be accessed via the MII ioctl()s.
>
> This is useful for systems where the device is connected without a PHY
> or where either information or actions outside the scope of the driver
> are required in order to use the PHYs.
Not that my opinion should hold much weight, having been absent from the
driver for some time, but yuck. Is there no better way to do this thatn
sprinkling poo all over it?
^ permalink raw reply
* Re: [RFC: 2.6 patch] hostap_hw.c:hfa384x_set_rid(): fix error handling
From: Jouni Malinen @ 2006-03-13 1:15 UTC (permalink / raw)
To: Adrian Bunk; +Cc: netdev, hostap, linux-kernel, linville
In-Reply-To: <20060309230646.GI21864@stusta.de>
On Fri, Mar 10, 2006 at 12:06:46AM +0100, Adrian Bunk wrote:
> The Coverity checker noted that the call to prism2_hw_reset() was dead
> code.
>
> Does this patch change the code to what was intended?
Thanks! Based on my CVS history, it looks like this was broken in 2002
when the access command was moved from another function and verification
of -ETIMEDOUT value was not moved correctly. The original behavior would
be achieved by changing your patch to call printk first before the moved
prism2_hw_reset(dev) call. I added this (with the re-ordered printk) to
my queue for wireless-2.6.
--
Jouni Malinen PGP id EFC895FA
^ permalink raw reply
* Re: [2.6 patch] hostap_ap.c:hostap_add_sta(): inconsequent NULL checking
From: Jouni Malinen @ 2006-03-13 1:23 UTC (permalink / raw)
To: Adrian Bunk; +Cc: hostap, netdev, linux-kernel
In-Reply-To: <20060310191026.GS21864@stusta.de>
On Fri, Mar 10, 2006 at 08:10:26PM +0100, Adrian Bunk wrote:
> The Coverity checker spotted this inconsequent NULL checking
> (unconditionally dereferencing directly after checking for NULL
> isn't a good idea).
Thanks! Added to my queue for wireless-2.6.
--
Jouni Malinen PGP id EFC895FA
^ permalink raw reply
* Re: [PATCH] TC: bug fixes to the "sample" clause
From: Russell Stuart @ 2006-03-13 4:44 UTC (permalink / raw)
To: hadi; +Cc: netdev, lartc
In-Reply-To: <1142082696.5184.53.camel@jzny2>
On Sat, 2006-03-11 at 08:11 -0500, jamal wrote:
> > On my machine tc does not parse filter "sample" for the u32
> > filter. Eg:
> >
> > tc filter add dev eth2 parent 1:0 protocol ip prio 1 u32 ht 801: \
> > classid 1:3 \
> > sample ip protocol 1 0xff match ip protocol 1 0xff
> > Illegal "sample"
> >
>
> The syntax is correct but ht 801: must exist - that is why it is being
> rejected.. So there is absolutely categorically _no way in hell_ your
> memset would have fixed it ;-> Apologies for being overdramatic ;->
You are wrong on both counts.
Firstly, the error message came from tc when it parsed
the line. If tc gets an error talking to the kernel it
says, among other things:
"We have an error talking to the kernel"
Ergo, it hadn't given the command to the kernel yet.
This is significant, because the only place that
knows whether ht 801: has been created or not is
the kernel. So obviously the error message can't
depend on whether the table had been created.
As it happens I did create the ht before issuing the
prior command when I first struck the bug - but I
didn't show it in my example because it was not
relevant.
As for _no way in hell_ - there are apparently more ways
in hell then you are aware of. If you look at the
function pack_key() in tc/f_u32.c, you will see it
assumes the "sel" parameter it is passed is initialised.
Without the added "memset()" it isn't - it just contains
random crap. Of course on some machines (perhaps yours?)
that random crap might be 0, and then it would work.
That is why I said at the start of my patch "On my
machine tc does not ...". On other machines the bug
may not appear.
> sample never worked 100% of the time with that hash. It works _most_ of
> the time with 256 buckets. Infact it will work some of the time as it is
> right now with 2.6.x. Can you post the output of tc -s filter ls on 2.6
> with and without your user space change?
Re: "sample never worked 100% of the time with that
hash". Can you give an example? As far as I know it
always worked.
Re: "it will work some of the time as it is right now
with 2.6.x". Yes - it will work when you are sampling
one byte. I am sampling port numbers, which are two
bytes. It will not work in any case where there are
two non-zero bytes.
Re: "Can you post the output of tc -s filter ls on 2.6
with and without your user space change?". Here it is:
With my change:
tc qdisc add dev eth0 root handle 1: htb
tc filter add dev eth0 parent 1:0 prio 1 protocol ip u32 ht 801: divisor 256
tc filter add dev eth0 parent 1:0 protocol ip prio 1 u32 ht 801: classid 1:0 sample tcp src 0x369 0xffff match tcp src 0x0369 0xffff
tc -s filter show dev eth0
filter parent 1: protocol ip pref 1 u32
filter parent 1: protocol ip pref 1 u32 fh 801: ht divisor 256
filter parent 1: protocol ip pref 1 u32 fh 801:3:800 order 2048 key ht 801 bkt 3 flowid 1:
match 03690000/ffff0000 at nexthdr+0
filter parent 1: protocol ip pref 1 u32 fh 800: ht divisor 1
On the orginal "tc" shipped with debian "sarge":
tc qdisc add dev eth0 root handle 1: htb
tc filter add dev eth0 parent 1:0 prio 1 protocol ip u32 ht 801: divisor 256
tc filter add dev eth0 parent 1:0 protocol ip prio 1 u32 ht 801: classid 1:0 sample tcp src 0x369 0xffff match tcp src 0x0369 0xffff
Illegal "sample"
Ooops. Looks like I can't get out of this without patching
and compiling:
tc qdisc add dev eth0 root handle 1: htb
tc filter add dev eth0 parent 1:0 prio 1 protocol ip u32 ht 801: divisor 256
tc filter add dev eth0 parent 1:0 protocol ip prio 1 u32 ht 801: classid 1:0 sample tcp src 0x369 0xffff match tcp src 0x0369 0xffff
tc -s filter show dev eth0filter parent 1: protocol ip pref 1 u32
filter parent 1: protocol ip pref 1 u32 fh 801: ht divisor 256
filter parent 1: protocol ip pref 1 u32 fh 801:6a:800 order 2048 key ht 801 bkt 6a flowid 1:
match 03690000/ffff0000 at nexthdr+0
filter parent 1: protocol ip pref 1 u32 fh 800: ht divisor 1
Note: this also answers you request in your other email re:
"can you give me an example that doesn't work".
> Heres how you should fix this:
> Patch1) fix kernel 2.4.x to be like 2.6.x
> patch 2) fix iproute2 to have the same syntax as for 2.6 and put a big
> bold note in the code that if anyone changes that part of the code to
> look at the kernel u32_hash_fold() routine.
> no need for the utsname check.
Why do it that way? If you want to put the 2.6 hashing
algorithm in 2.4 then go ahead - but that is a separate
decision which is not related to the issue of making tc
backwards compatible. Making tc work with all versions of
the kernel is what I am doing there. As an example of why
this is a good idea, Debian ships 2.4 and 2.6 kernels,
and one version of tc. That tc should work with both
kernels.
Finally, regarding which hashing algorithm is better,
your results differ from mine. First a bit of
background: I am trying make VOIP work over some 256/64
and 512/128 links that carry all sorts of other traffic.
The patches you see here are a result of me trying to
make that work over a range of sites (companies and
home setups). The end result is that it did work, better
than I expected it to. On a 512/128 ADSL link, I can:
a. Saturate the incoming direction with a large wget,
b. Saturate the outgoing direction with a large wget,
c. Hit the incoming direction with a "while :; do
wget http://www.google.com/ -O /dev/null; done".
d. Hit the outgoing direction with an external box
doing the same while loop.
While all that is going on, I can sustain 2 VOIP calls
with perfect clarity on that link. I wasn't expecting to
be able to pull that off. To pull it off I created the
u32 filter from hell. This long winded explanation is to
forestall the inevitable "why the hell you want want to do
that" flame when you see the script that follows.
You can find the shell script that creates the filter here:
http://www.stuart.id.au/russell/files/tc/setup-traffic-control.sh
The script itself is not that important. What is important
is that it is a real-life use of u32, and there are approx
1200 hashed u32 filter lines.
So how to means how good a job the hash is doing. The
easiest would seem to be to use a least squares fit, ie:
Number of elements to be hashed = E
Number of buckets = B (== 256)
Optimal number of elements per bucket = E/B
Hash function "goodness" metric = M =
sqrt(sum foreach bucket i: [ (NrOfElementsInBucket(i) - E/B)^2 ] / B)
For a good hash function M < 1. The bigger M is the
worse the hash function is. I wrote a python program to
compute M for my u32 filter. The python program can be
found here:
http://www.stuart.id.au/russell/files/tc/tc-ports
The dataset it operates on can be found here:
http://www.stuart.id.au/russell/files/tc/m.py
Results:
tcp 2.6: E=534 M=2.35
tcp 2.4: E=534 M=0.82
udp 2.6: E=711 M=2.91
udp 2.4: E=711 M=0.92
As you can probably tell, I see the new hash function in 2.6
as a backward step - not an improvement.
^ 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