Netdev List
 help / color / mirror / Atom feed
* Re: [patch 3/4] net: Percpufy frequently used variables -- proto.sockets_allocated
From: Andrew Morton @ 2006-01-28  1:18 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: kiran, davem, linux-kernel, shai, netdev, pravins
In-Reply-To: <43DAC46B.3010200@cosmosbay.com>

Eric Dumazet <dada1@cosmosbay.com> wrote:
>
> [PATCH] Add atomic_long_xchg() and atomic_long_cmpxchg() wrappers
> 
> ...
>  
> +static inline long atomic_long_xchg(atomic_long_t *l, long val)
> +{
> +	atomic64_t *v = (atomic64_t *)l;
> +	return atomic64_xchg(v, val);

All we need now is some implementations of atomic64_xchg()  ;)

^ permalink raw reply

* Re: [patch 3/4] net: Percpufy frequently used variables -- proto.sockets_allocated
From: Ravikiran G Thirumalai @ 2006-01-28  4:52 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Andrew Morton, davem, linux-kernel, shai, netdev, pravins
In-Reply-To: <43DABC37.6070603@cosmosbay.com>

On Sat, Jan 28, 2006 at 01:35:03AM +0100, Eric Dumazet wrote:
> Eric Dumazet a écrit :
> >Andrew Morton a écrit :
> >>Eric Dumazet <dada1@cosmosbay.com> wrote:
> >
> >#ifdef CONFIG_SMP
> >void percpu_counter_mod(struct percpu_counter *fbc, long amount)
> >{
> >	long old, new;
> >	atomic_long_t *pcount;
> >
> >	pcount = per_cpu_ptr(fbc->counters, get_cpu());
> >start:
> >	old = atomic_long_read(pcount);
> >	new = old + amount;
> >	if (new >= FBC_BATCH || new <= -FBC_BATCH) {
> >		if (unlikely(atomic_long_cmpxchg(pcount, old, 0) != old))
> >			goto start;
> >		atomic_long_add(new, &fbc->count);
> >	} else
> >		atomic_long_add(amount, pcount);
> >
> >	put_cpu();
> >}
> >EXPORT_SYMBOL(percpu_counter_mod);
> >
> >long percpu_counter_read_accurate(struct percpu_counter *fbc)
> >{
> >	long res = 0;
> >	int cpu;
> >	atomic_long_t *pcount;
> >
> >	for_each_cpu(cpu) {
> >		pcount = per_cpu_ptr(fbc->counters, cpu);
> >		/* dont dirty cache line if not necessary */
> >		if (atomic_long_read(pcount))
> >			res += atomic_long_xchg(pcount, 0);
				--------------------------->  (A)
> >	}
> 

> 	atomic_long_add(res, &fbc->count);
				--------------------------->  (B)
> 	res = atomic_long_read(&fbc->count);
> 
> >	return res;
> >}

The read is still theoritically FBC_BATCH * NR_CPUS inaccurate no?
What happens when other cpus update  their local counters at (A) and (B)?

(I am hoping we don't need percpu_counter_read_accurate anywhere yet and
this is just demo ;).  I certainly don't want to go on all cpus for read / 
add cmpxchg on the write path for the proto counters that started this 
discussion)

Thanks,
Kiran

^ permalink raw reply

* Re: [patch 3/4] net: Percpufy frequently used variables -- proto.sockets_allocated
From: Eric Dumazet @ 2006-01-28  7:19 UTC (permalink / raw)
  To: Ravikiran G Thirumalai
  Cc: Andrew Morton, davem, linux-kernel, shai, netdev, pravins
In-Reply-To: <20060128045248.GA3584@localhost.localdomain>

[-- Attachment #1: Type: text/plain, Size: 1929 bytes --]

Ravikiran G Thirumalai a écrit :
> On Sat, Jan 28, 2006 at 01:35:03AM +0100, Eric Dumazet wrote:
>> Eric Dumazet a écrit :
>>> Andrew Morton a écrit :
>>>> Eric Dumazet <dada1@cosmosbay.com> wrote:
>>>
>>> long percpu_counter_read_accurate(struct percpu_counter *fbc)
>>> {
>>> 	long res = 0;
>>> 	int cpu;
>>> 	atomic_long_t *pcount;
>>>
>>> 	for_each_cpu(cpu) {
>>> 		pcount = per_cpu_ptr(fbc->counters, cpu);
>>> 		/* dont dirty cache line if not necessary */
>>> 		if (atomic_long_read(pcount))
>>> 			res += atomic_long_xchg(pcount, 0);
> 				--------------------------->  (A)
>>> 	}
> 
>> 	atomic_long_add(res, &fbc->count);
> 				--------------------------->  (B)
>> 	res = atomic_long_read(&fbc->count);
>>
>>> 	return res;
>>> }
> 
> The read is still theoritically FBC_BATCH * NR_CPUS inaccurate no?
> What happens when other cpus update  their local counters at (A) and (B)?

Well, after  atomic_read(&some_atomic) or percpu_counter_read_accurate(&s) the 
  'value' you got may be inaccurate by whatever... You cannot 'freeze the 
atomic / percpu_counter and gets its accurate value'. All you can do is 
'atomically add/remove some value from this counter (atomic or percpu_counter))

See percpu_counter_read_accurate() as an attempt to collect all local offset 
(and atomically set them to 0) and atomically reajust the central fbc->count 
to with the sum of all these offsets. Kind of a consolidation that might be 
driven by a user request (read /proc/sys/...) or a periodic timer.



> 
> (I am hoping we don't need percpu_counter_read_accurate anywhere yet and
> this is just demo ;).  I certainly don't want to go on all cpus for read / 
> add cmpxchg on the write path for the proto counters that started this 
> discussion)

As pointed by Andrew (If you decode carefully its short sentences :) ), all 
you really need is atomic_long_xchg() (only in slow path), and 
atomic_long_{read/add} in fast path)


Eric

[-- Attachment #2: functions --]
[-- Type: text/plain, Size: 1050 bytes --]

struct percpu_counter {
	atomic_long_t count;
	atomic_long_t *counters;
};

#ifdef CONFIG_SMP
void percpu_counter_mod(struct percpu_counter *fbc, long amount)
{
        long new;
	atomic_long_t *pcount;

	pcount = per_cpu_ptr(fbc->counters, get_cpu());

        new = atomic_long_read(pcount) + amount;
 
	if (new >= FBC_BATCH || new <= -FBC_BATCH) {
                new = atomic_long_xchg(pcount, 0) + amount;
                if (new)
                        atomic_long_add(new, &fbc->count);
	} else
		atomic_long_add(amount, pcount);

	put_cpu();
}
EXPORT_SYMBOL(percpu_counter_mod);

long percpu_counter_read_accurate(struct percpu_counter *fbc)
{
	long res = 0;
	int cpu;
	atomic_long_t *pcount;

	for_each_cpu(cpu) {
		pcount = per_cpu_ptr(fbc->counters, cpu);
		/* dont dirty cache line if not necessary */
		if (atomic_long_read(pcount))
			res += atomic_long_xchg(pcount, 0);
	}
        atomic_long_add(res, &fbc->count);
        return atomic_long_read(&fbc->count);
}
EXPORT_SYMBOL(percpu_counter_read_accurate);
#endif /* CONFIG_SMP */


^ permalink raw reply

* Re: e100 oops on resume
From: Mattia Dongili @ 2006-01-28 11:53 UTC (permalink / raw)
  To: Stefan Seyfried
  Cc: Jesse Brandeburg, Olaf Kirch, Linux Kernel Mailing List, netdev
In-Reply-To: <20060126190236.GA12481@suse.de>

On Thu, Jan 26, 2006 at 08:02:37PM +0100, Stefan Seyfried wrote:
> On Wed, Jan 25, 2006 at 04:28:48PM -0800, Jesse Brandeburg wrote:
>  
> > Okay I reproduced the issue on 2.6.15.1 (with S1 sleep) and was able
> > to show that my patch that just removes e100_init_hw works okay for
> > me.  Let me know how it goes for you, I think this is a good fix.
> 
> worked for me in the Compaq Armada e500 and reportedly also fixed the
> SONY that originally uncovered it.

confirmed here too. The patch fixes S3 resume on this Sony (GR7/K)
running 2.6.16-rc1-mm3.

0000:02:08.0 Ethernet controller: Intel Corporation 82801CAM (ICH3) PRO/100 VE (LOM) Ethernet Controller (rev 41)
	Subsystem: Sony Corporation Vaio PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
	Flags: bus master, medium devsel, latency 66, IRQ 9
	Memory at d0204000 (32-bit, non-prefetchable) [size=4K]
	I/O ports at 4000 [size=64]
	Capabilities: <available only to root>

thanks
-- 
mattia
:wq!

^ permalink raw reply

* Re: e100 oops on resume
From: Jesse Brandeburg @ 2006-01-28 19:53 UTC (permalink / raw)
  To: Jeff Garzik
  Cc: Stefan Seyfried, Jesse Brandeburg, Olaf Kirch,
	Linux Kernel Mailing List, netdev, Jesse Brandeburg, Jeff Kirsher
In-Reply-To: <20060128115335.GA4511@inferi.kami.home>

[-- Attachment #1: Type: text/plain, Size: 737 bytes --]

On 1/28/06, Mattia Dongili <malattia@linux.it> wrote:
> On Thu, Jan 26, 2006 at 08:02:37PM +0100, Stefan Seyfried wrote:
> > On Wed, Jan 25, 2006 at 04:28:48PM -0800, Jesse Brandeburg wrote:
> >
> > > Okay I reproduced the issue on 2.6.15.1 (with S1 sleep) and was able
> > > to show that my patch that just removes e100_init_hw works okay for
> > > me.  Let me know how it goes for you, I think this is a good fix.
> >
> > worked for me in the Compaq Armada e500 and reportedly also fixed the
> > SONY that originally uncovered it.
>
> confirmed here too. The patch fixes S3 resume on this Sony (GR7/K)
> running 2.6.16-rc1-mm3.

excellent news! thanks for testing.

Jeff, could you please apply to 2.6.16-rcX

Jesse

[-- Attachment #2: e100_resume_no_init.patch --]
[-- Type: application/octet-stream, Size: 818 bytes --]

e100: remove init_hw call to fix panic

Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>

e100 seems to have had a long standing bug where e100_init_hw was being
called when it should not have been.  This caused a panic due to recent
changes that rely on correct set up in the driver, and more robust error
paths.
---

 drivers/net/e100.c |    2 --
 1 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/drivers/net/e100.c b/drivers/net/e100.c
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -2752,8 +2752,6 @@ static int e100_resume(struct pci_dev *p
 	retval = pci_enable_wake(pdev, 0, 0);
 	if (retval)
 		DPRINTK(PROBE,ERR, "Error clearing wake events\n");
-	if(e100_hw_init(nic))
-		DPRINTK(HW, ERR, "e100_hw_init failed\n");
 
 	netif_device_attach(netdev);
 	if(netif_running(netdev))

^ permalink raw reply

* [git patches] net driver fixes
From: Jeff Garzik @ 2006-01-28 21:44 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:

 arch/ppc/syslib/mv64x60.c         |    4 -
 drivers/net/acenic.c              |    4 +
 drivers/net/b44.c                 |    5 +
 drivers/net/bonding/bond_main.c   |    2 
 drivers/net/mv643xx_eth.c         |  108 ++++++++++++++++----------------------
 drivers/net/s2io.c                |    2 
 drivers/net/wireless/orinoco_cs.c |    4 -
 include/net/ieee80211.h           |    4 -
 net/ieee80211/ieee80211_rx.c      |   22 +++++--
 net/ieee80211/ieee80211_wx.c      |   12 +++-
 10 files changed, 89 insertions(+), 78 deletions(-)

Ananda Raju:
      s2io: scatter-gather fix

Dale Farnsworth:
      mv643xx_eth: Fix spinlock recursion bug
      mv643xx_eth: Whitespace cleanup
      mv643xx_eth: Fix for building as a module

Eric Sesterhenn:
      bonding: fix ->get_settings error checking
      acenic: fix checking of read_eeprom_byte() return values

Paolo Galtieri:
      mv643xx_eth: Update dev->last_rx on packet receive

Stephen Hemminger:
      b44: fix laptop carrier detect

Valdis.Kletnieks@vt.edu:
      orinoco_cs: tweak Vcc debugging messages

Zhu Yi:
      ieee80211: Fix problem with not decrypting broadcast packets
      ieee80211: Fix iwlist scan can only show about 20 APs
      ieee80211: Fix A band min and max channel definitions

diff --git a/arch/ppc/syslib/mv64x60.c b/arch/ppc/syslib/mv64x60.c
index 94ea346..1f01b7e 100644
--- a/arch/ppc/syslib/mv64x60.c
+++ b/arch/ppc/syslib/mv64x60.c
@@ -313,7 +313,7 @@ static struct platform_device mpsc1_devi
 };
 #endif
 
-#ifdef CONFIG_MV643XX_ETH
+#if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE)
 static struct resource mv64x60_eth_shared_resources[] = {
 	[0] = {
 		.name	= "ethernet shared base",
@@ -456,7 +456,7 @@ static struct platform_device *mv64x60_p
 	&mpsc0_device,
 	&mpsc1_device,
 #endif
-#ifdef CONFIG_MV643XX_ETH
+#if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE)
 	&mv64x60_eth_shared_device,
 #endif
 #ifdef CONFIG_MV643XX_ETH_0
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
index b8953de..b508812 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -1002,6 +1002,8 @@ static int __devinit ace_init(struct net
 
 	mac1 = 0;
 	for(i = 0; i < 4; i++) {
+		int tmp;
+
 		mac1 = mac1 << 8;
 		tmp = read_eeprom_byte(dev, 0x8c+i);
 		if (tmp < 0) {
@@ -1012,6 +1014,8 @@ static int __devinit ace_init(struct net
 	}
 	mac2 = 0;
 	for(i = 4; i < 8; i++) {
+		int tmp;
+
 		mac2 = mac2 << 8;
 		tmp = read_eeprom_byte(dev, 0x8c+i);
 		if (tmp < 0) {
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index df9d6e8..c3267e4 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -1399,7 +1399,6 @@ static int b44_open(struct net_device *d
 	b44_init_rings(bp);
 	b44_init_hw(bp);
 
-	netif_carrier_off(dev);
 	b44_check_phy(bp);
 
 	err = request_irq(dev->irq, b44_interrupt, SA_SHIRQ, dev->name, dev);
@@ -1464,7 +1463,7 @@ static int b44_close(struct net_device *
 #endif
 	b44_halt(bp);
 	b44_free_rings(bp);
-	netif_carrier_off(bp->dev);
+	netif_carrier_off(dev);
 
 	spin_unlock_irq(&bp->lock);
 
@@ -2000,6 +1999,8 @@ static int __devinit b44_init_one(struct
 	dev->irq = pdev->irq;
 	SET_ETHTOOL_OPS(dev, &b44_ethtool_ops);
 
+	netif_carrier_off(dev);
+
 	err = b44_get_invariants(bp);
 	if (err) {
 		printk(KERN_ERR PFX "Problem fetching invariants of chip, "
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 2582d98..4ff006c 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -576,7 +576,7 @@ static int bond_update_speed_duplex(stru
 	slave->duplex = DUPLEX_FULL;
 
 	if (slave_dev->ethtool_ops) {
-		u32 res;
+		int res;
 
 		if (!slave_dev->ethtool_ops->get_settings) {
 			return -1;
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 40ae36b..7ef4b04 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -444,6 +444,7 @@ static int mv643xx_eth_receive_queue(str
 			netif_rx(skb);
 #endif
 		}
+		dev->last_rx = jiffies;
 	}
 
 	return received_packets;
@@ -461,7 +462,7 @@ static int mv643xx_eth_receive_queue(str
  */
 
 static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id,
-							struct pt_regs *regs)
+						struct pt_regs *regs)
 {
 	struct net_device *dev = (struct net_device *)dev_id;
 	struct mv643xx_private *mp = netdev_priv(dev);
@@ -1047,16 +1048,15 @@ static int mv643xx_poll(struct net_devic
 
 static inline unsigned int has_tiny_unaligned_frags(struct sk_buff *skb)
 {
-        unsigned int frag;
-        skb_frag_t *fragp;
+	unsigned int frag;
+	skb_frag_t *fragp;
 
-        for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
-                fragp = &skb_shinfo(skb)->frags[frag];
-                if (fragp->size <= 8 && fragp->page_offset & 0x7)
-                        return 1;
-
-        }
-        return 0;
+	for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
+		fragp = &skb_shinfo(skb)->frags[frag];
+		if (fragp->size <= 8 && fragp->page_offset & 0x7)
+			return 1;
+	}
+	return 0;
 }
 
 
@@ -2137,26 +2137,26 @@ static void eth_port_set_multicast_list(
 	 */
 	if ((dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI)) {
 		for (table_index = 0; table_index <= 0xFC; table_index += 4) {
-			 /* Set all entries in DA filter special multicast
-			  * table (Ex_dFSMT)
-			  * Set for ETH_Q0 for now
-			  * Bits
-			  * 0	  Accept=1, Drop=0
-			  * 3-1  Queue	 ETH_Q0=0
-			  * 7-4  Reserved = 0;
-			  */
-			 mv_write(MV643XX_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(eth_port_num) + table_index, 0x01010101);
-
-			 /* Set all entries in DA filter other multicast
-			  * table (Ex_dFOMT)
-			  * Set for ETH_Q0 for now
-			  * Bits
-			  * 0	  Accept=1, Drop=0
-			  * 3-1  Queue	 ETH_Q0=0
-			  * 7-4  Reserved = 0;
-			  */
-			 mv_write(MV643XX_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE(eth_port_num) + table_index, 0x01010101);
-       	}
+			/* Set all entries in DA filter special multicast
+			 * table (Ex_dFSMT)
+			 * Set for ETH_Q0 for now
+			 * Bits
+			 * 0	  Accept=1, Drop=0
+			 * 3-1  Queue	 ETH_Q0=0
+			 * 7-4  Reserved = 0;
+			 */
+			mv_write(MV643XX_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(eth_port_num) + table_index, 0x01010101);
+
+			/* Set all entries in DA filter other multicast
+			 * table (Ex_dFOMT)
+			 * Set for ETH_Q0 for now
+			 * Bits
+			 * 0	  Accept=1, Drop=0
+			 * 3-1  Queue	 ETH_Q0=0
+			 * 7-4  Reserved = 0;
+			 */
+			mv_write(MV643XX_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE(eth_port_num) + table_index, 0x01010101);
+		}
 		return;
 	}
 
@@ -2617,7 +2617,6 @@ static ETH_FUNC_RET_STATUS eth_port_send
 	struct eth_tx_desc *current_descriptor;
 	struct eth_tx_desc *first_descriptor;
 	u32 command;
-	unsigned long flags;
 
 	/* Do not process Tx ring in case of Tx ring resource error */
 	if (mp->tx_resource_err)
@@ -2634,8 +2633,6 @@ static ETH_FUNC_RET_STATUS eth_port_send
 		return ETH_ERROR;
 	}
 
-	spin_lock_irqsave(&mp->lock, flags);
-
 	mp->tx_ring_skbs++;
 	BUG_ON(mp->tx_ring_skbs > mp->tx_ring_size);
 
@@ -2685,15 +2682,11 @@ static ETH_FUNC_RET_STATUS eth_port_send
 		mp->tx_resource_err = 1;
 		mp->tx_curr_desc_q = tx_first_desc;
 
-		spin_unlock_irqrestore(&mp->lock, flags);
-
 		return ETH_QUEUE_LAST_RESOURCE;
 	}
 
 	mp->tx_curr_desc_q = tx_next_desc;
 
-	spin_unlock_irqrestore(&mp->lock, flags);
-
 	return ETH_OK;
 }
 #else
@@ -2704,14 +2697,11 @@ static ETH_FUNC_RET_STATUS eth_port_send
 	int tx_desc_used;
 	struct eth_tx_desc *current_descriptor;
 	unsigned int command_status;
-	unsigned long flags;
 
 	/* Do not process Tx ring in case of Tx ring resource error */
 	if (mp->tx_resource_err)
 		return ETH_QUEUE_FULL;
 
-	spin_lock_irqsave(&mp->lock, flags);
-
 	mp->tx_ring_skbs++;
 	BUG_ON(mp->tx_ring_skbs > mp->tx_ring_size);
 
@@ -2742,12 +2732,9 @@ static ETH_FUNC_RET_STATUS eth_port_send
 	/* Check for ring index overlap in the Tx desc ring */
 	if (tx_desc_curr == tx_desc_used) {
 		mp->tx_resource_err = 1;
-
-		spin_unlock_irqrestore(&mp->lock, flags);
 		return ETH_QUEUE_LAST_RESOURCE;
 	}
 
-	spin_unlock_irqrestore(&mp->lock, flags);
 	return ETH_OK;
 }
 #endif
@@ -2898,8 +2885,10 @@ static ETH_FUNC_RET_STATUS eth_port_rece
 	p_pkt_info->return_info = mp->rx_skb[rx_curr_desc];
 	p_pkt_info->l4i_chk = p_rx_desc->buf_size;
 
-	/* Clean the return info field to indicate that the packet has been */
-	/* moved to the upper layers					    */
+	/*
+	 * Clean the return info field to indicate that the
+	 * packet has been moved to the upper layers
+	 */
 	mp->rx_skb[rx_curr_desc] = NULL;
 
 	/* Update current index in data structure */
@@ -2980,7 +2969,7 @@ struct mv643xx_stats {
 };
 
 #define MV643XX_STAT(m) sizeof(((struct mv643xx_private *)0)->m), \
-		      offsetof(struct mv643xx_private, m)
+					offsetof(struct mv643xx_private, m)
 
 static const struct mv643xx_stats mv643xx_gstrings_stats[] = {
 	{ "rx_packets", MV643XX_STAT(stats.rx_packets) },
@@ -3131,9 +3120,8 @@ mv643xx_get_settings(struct net_device *
 	return 0;
 }
 
-static void
-mv643xx_get_drvinfo(struct net_device *netdev,
-                       struct ethtool_drvinfo *drvinfo)
+static void mv643xx_get_drvinfo(struct net_device *netdev,
+				struct ethtool_drvinfo *drvinfo)
 {
 	strncpy(drvinfo->driver,  mv643xx_driver_name, 32);
 	strncpy(drvinfo->version, mv643xx_driver_version, 32);
@@ -3142,39 +3130,37 @@ mv643xx_get_drvinfo(struct net_device *n
 	drvinfo->n_stats = MV643XX_STATS_LEN;
 }
 
-static int 
-mv643xx_get_stats_count(struct net_device *netdev)
+static int mv643xx_get_stats_count(struct net_device *netdev)
 {
 	return MV643XX_STATS_LEN;
 }
 
-static void 
-mv643xx_get_ethtool_stats(struct net_device *netdev, 
-		struct ethtool_stats *stats, uint64_t *data)
+static void mv643xx_get_ethtool_stats(struct net_device *netdev,
+				struct ethtool_stats *stats, uint64_t *data)
 {
 	struct mv643xx_private *mp = netdev->priv;
 	int i;
 
 	eth_update_mib_counters(mp);
 
-	for(i = 0; i < MV643XX_STATS_LEN; i++) {
+	for (i = 0; i < MV643XX_STATS_LEN; i++) {
 		char *p = (char *)mp+mv643xx_gstrings_stats[i].stat_offset;	
-		data[i] = (mv643xx_gstrings_stats[i].sizeof_stat == 
+		data[i] = (mv643xx_gstrings_stats[i].sizeof_stat ==
 			sizeof(uint64_t)) ? *(uint64_t *)p : *(uint32_t *)p;
 	}
 }
 
-static void 
-mv643xx_get_strings(struct net_device *netdev, uint32_t stringset, uint8_t *data)
+static void mv643xx_get_strings(struct net_device *netdev, uint32_t stringset,
+				uint8_t *data)
 {
 	int i;
 
 	switch(stringset) {
 	case ETH_SS_STATS:
 		for (i=0; i < MV643XX_STATS_LEN; i++) {
-			memcpy(data + i * ETH_GSTRING_LEN, 
-			mv643xx_gstrings_stats[i].stat_string,
-			ETH_GSTRING_LEN);
+			memcpy(data + i * ETH_GSTRING_LEN,
+					mv643xx_gstrings_stats[i].stat_string,
+					ETH_GSTRING_LEN);
 		}
 		break;
 	}
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 89c4678..49b597c 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -3586,7 +3586,7 @@ static int s2io_xmit(struct sk_buff *skb
 		txdp->Buffer_Pointer = (u64) pci_map_page
 		    (sp->pdev, frag->page, frag->page_offset,
 		     frag->size, PCI_DMA_TODEVICE);
-		txdp->Control_1 |= TXD_BUFFER0_SIZE(frag->size);
+		txdp->Control_1 = TXD_BUFFER0_SIZE(frag->size);
 		if (skb_shinfo(skb)->ufo_size)
 			txdp->Control_1 |= TXD_UFO_EN;
 	}
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
index b664708..3c128b6 100644
--- a/drivers/net/wireless/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco_cs.c
@@ -261,13 +261,13 @@ orinoco_cs_config(dev_link_t *link)
 		/* Note that the CIS values need to be rescaled */
 		if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
 			if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
-				DEBUG(2, "orinoco_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n",  conf.Vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
+				DEBUG(2, "orinoco_cs_config: Vcc mismatch (conf.Vcc = %d, cfg CIS = %d)\n",  conf.Vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
 				if (!ignore_cis_vcc)
 					goto next_entry;
 			}
 		} else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
 			if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) {
-				DEBUG(2, "orinoco_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n",  conf.Vcc, dflt.vcc.param[CISTPL_POWER_VNOM] / 10000);
+				DEBUG(2, "orinoco_cs_config: Vcc mismatch (conf.Vcc = %d, dflt CIS = %d)\n",  conf.Vcc, dflt.vcc.param[CISTPL_POWER_VNOM] / 10000);
 				if(!ignore_cis_vcc)
 					goto next_entry;
 			}
diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h
index df05f46..9a92aef 100644
--- a/include/net/ieee80211.h
+++ b/include/net/ieee80211.h
@@ -803,9 +803,9 @@ enum ieee80211_state {
 #define IEEE80211_24GHZ_MAX_CHANNEL 14
 #define IEEE80211_24GHZ_CHANNELS    14
 
-#define IEEE80211_52GHZ_MIN_CHANNEL 36
+#define IEEE80211_52GHZ_MIN_CHANNEL 34
 #define IEEE80211_52GHZ_MAX_CHANNEL 165
-#define IEEE80211_52GHZ_CHANNELS    32
+#define IEEE80211_52GHZ_CHANNELS    131
 
 enum {
 	IEEE80211_CH_PASSIVE_ONLY = (1 << 0),
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c
index 7a12180..695d047 100644
--- a/net/ieee80211/ieee80211_rx.c
+++ b/net/ieee80211/ieee80211_rx.c
@@ -350,6 +350,7 @@ int ieee80211_rx(struct ieee80211_device
 	u8 src[ETH_ALEN];
 	struct ieee80211_crypt_data *crypt = NULL;
 	int keyidx = 0;
+	int can_be_decrypted = 0;
 
 	hdr = (struct ieee80211_hdr_4addr *)skb->data;
 	stats = &ieee->stats;
@@ -410,12 +411,23 @@ int ieee80211_rx(struct ieee80211_device
 		return 1;
 	}
 
-	if (is_multicast_ether_addr(hdr->addr1)
-	    ? ieee->host_mc_decrypt : ieee->host_decrypt) {
+	can_be_decrypted = (is_multicast_ether_addr(hdr->addr1) ||
+			    is_broadcast_ether_addr(hdr->addr2)) ?
+	    ieee->host_mc_decrypt : ieee->host_decrypt;
+
+	if (can_be_decrypted) {
 		int idx = 0;
-		if (skb->len >= hdrlen + 3)
+		if (skb->len >= hdrlen + 3) {
+			/* Top two-bits of byte 3 are the key index */
 			idx = skb->data[hdrlen + 3] >> 6;
+		}
+
+		/* ieee->crypt[] is WEP_KEY (4) in length.  Given that idx
+		 * is only allowed 2-bits of storage, no value of idx can
+		 * be provided via above code that would result in idx
+		 * being out of range */
 		crypt = ieee->crypt[idx];
+
 #ifdef NOT_YET
 		sta = NULL;
 
@@ -553,7 +565,7 @@ int ieee80211_rx(struct ieee80211_device
 
 	/* skb: hdr + (possibly fragmented, possibly encrypted) payload */
 
-	if (ieee->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
+	if ((fc & IEEE80211_FCTL_PROTECTED) && can_be_decrypted &&
 	    (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0)
 		goto rx_dropped;
 
@@ -617,7 +629,7 @@ int ieee80211_rx(struct ieee80211_device
 
 	/* skb: hdr + (possible reassembled) full MSDU payload; possibly still
 	 * encrypted/authenticated */
-	if (ieee->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
+	if ((fc & IEEE80211_FCTL_PROTECTED) && can_be_decrypted &&
 	    ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt))
 		goto rx_dropped;
 
diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c
index 23e1630..f87c6b8 100644
--- a/net/ieee80211/ieee80211_wx.c
+++ b/net/ieee80211/ieee80211_wx.c
@@ -232,15 +232,18 @@ static char *ipw2100_translate_scan(stru
 	return start;
 }
 
+#define SCAN_ITEM_SIZE 128
+
 int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
 			  struct iw_request_info *info,
 			  union iwreq_data *wrqu, char *extra)
 {
 	struct ieee80211_network *network;
 	unsigned long flags;
+	int err = 0;
 
 	char *ev = extra;
-	char *stop = ev + IW_SCAN_MAX_DATA;
+	char *stop = ev + wrqu->data.length;
 	int i = 0;
 
 	IEEE80211_DEBUG_WX("Getting scan\n");
@@ -249,6 +252,11 @@ int ieee80211_wx_get_scan(struct ieee802
 
 	list_for_each_entry(network, &ieee->network_list, list) {
 		i++;
+		if (stop - ev < SCAN_ITEM_SIZE) {
+			err = -E2BIG;
+			break;
+		}
+
 		if (ieee->scan_age == 0 ||
 		    time_after(network->last_scanned + ieee->scan_age, jiffies))
 			ev = ipw2100_translate_scan(ieee, ev, stop, network);
@@ -270,7 +278,7 @@ int ieee80211_wx_get_scan(struct ieee802
 
 	IEEE80211_DEBUG_WX("exit: %d networks returned.\n", i);
 
-	return 0;
+	return err;
 }
 
 int ieee80211_wx_set_encode(struct ieee80211_device *ieee,

^ permalink raw reply related

* Re: [patch 3/4] net: Percpufy frequently used variables -- proto.sockets_allocated
From: Benjamin LaHaise @ 2006-01-29  0:44 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Andrew Morton, kiran, davem, linux-kernel, shai, netdev, pravins
In-Reply-To: <43DABAA4.8040208@cosmosbay.com>

On Sat, Jan 28, 2006 at 01:28:20AM +0100, Eric Dumazet wrote:
> We might use atomic_long_t only (and no spinlocks)
> Something like this ?

Erk, complex and slow...  Try using local_t instead, which is substantially 
cheaper on the P4 as it doesn't use the lock prefix and act as a memory 
barrier.  See asm/local.h.

		-ben

^ permalink raw reply

* Re: [patch 3/4] net: Percpufy frequently used variables -- proto.sockets_allocated
From: Andrew Morton @ 2006-01-29  0:55 UTC (permalink / raw)
  To: Benjamin LaHaise; +Cc: dada1, kiran, davem, linux-kernel, shai, netdev, pravins
In-Reply-To: <20060129004459.GA24099@kvack.org>

Benjamin LaHaise <bcrl@kvack.org> wrote:
>
> On Sat, Jan 28, 2006 at 01:28:20AM +0100, Eric Dumazet wrote:
> > We might use atomic_long_t only (and no spinlocks)
> > Something like this ?
> 
> Erk, complex and slow...  Try using local_t instead, which is substantially 
> cheaper on the P4 as it doesn't use the lock prefix and act as a memory 
> barrier.  See asm/local.h.
> 

local_t isn't much use until we get rid of asm-generic/local.h.  Bloaty,
racy with nested interrupts.

^ permalink raw reply

* Re: [patch 3/4] net: Percpufy frequently used variables -- proto.sockets_allocated
From: Benjamin LaHaise @ 2006-01-29  1:19 UTC (permalink / raw)
  To: Andrew Morton; +Cc: dada1, kiran, davem, linux-kernel, shai, netdev, pravins
In-Reply-To: <20060128165549.262f2b90.akpm@osdl.org>

On Sat, Jan 28, 2006 at 04:55:49PM -0800, Andrew Morton wrote:
> local_t isn't much use until we get rid of asm-generic/local.h.  Bloaty,
> racy with nested interrupts.

The overuse of atomics is horrific in what is being proposed.  All the
major architectures except powerpc (i386, x86-64, ia64, and sparc64) 
implement local_t.  It would make far more sense to push the last few 
stragglers (which mostly seem to be uniprocessor) into writing the 
appropriate implementations.  Perhaps it's time to add a #error in 
asm-generic/local.h?

		-ben
-- 
"Ladies and gentlemen, I'm sorry to interrupt, but the police are here 
and they've asked us to stop the party."  Don't Email: <dont@kvack.org>.

^ permalink raw reply

* Re: [patch 3/4] net: Percpufy frequently used variables -- proto.sockets_allocated
From: Andrew Morton @ 2006-01-29  1:29 UTC (permalink / raw)
  To: Benjamin LaHaise; +Cc: dada1, kiran, davem, linux-kernel, shai, netdev, pravins
In-Reply-To: <20060129011944.GB24099@kvack.org>

Benjamin LaHaise <bcrl@kvack.org> wrote:
>
> On Sat, Jan 28, 2006 at 04:55:49PM -0800, Andrew Morton wrote:
> > local_t isn't much use until we get rid of asm-generic/local.h.  Bloaty,
> > racy with nested interrupts.
> 
> The overuse of atomics is horrific in what is being proposed.

Well yeah, it wasn't really a very serious proposal.  There's some
significant work yet to be done on this stuff.

> Perhaps it's time to add a #error in asm-generic/local.h?

heh, or #warning "you suck" or something.

^ permalink raw reply

* Re: [patch 3/4] net: Percpufy frequently used variables -- proto.sockets_allocated
From: Kyle McMartin @ 2006-01-29  1:45 UTC (permalink / raw)
  To: Benjamin LaHaise
  Cc: Andrew Morton, dada1, kiran, davem, linux-kernel, shai, netdev,
	pravins
In-Reply-To: <20060129011944.GB24099@kvack.org>

On Sat, Jan 28, 2006 at 08:19:44PM -0500, Benjamin LaHaise wrote:
> The overuse of atomics is horrific in what is being proposed.  All the
> major architectures except powerpc (i386, x86-64, ia64, and sparc64) 
> implement local_t.  It would make far more sense to push the last few 
> stragglers (which mostly seem to be uniprocessor) into writing the 
> appropriate implementations.  Perhaps it's time to add a #error in 
> asm-generic/local.h?
>

Surely asm-generic/local.h could now be reimplemented using atomic_long_t
to kill that aberration that is the BITS_PER_LONG != 32 case currently...? 

^ permalink raw reply

* Re: [patch 3/4] net: Percpufy frequently used variables -- proto.sockets_allocated
From: Andi Kleen @ 2006-01-29  5:38 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Benjamin LaHaise, dada1, kiran, davem, linux-kernel, shai, netdev,
	pravins, linux-arch
In-Reply-To: <20060128165549.262f2b90.akpm@osdl.org>

[adding linux-arch]

On Sunday 29 January 2006 01:55, Andrew Morton wrote:
> Benjamin LaHaise <bcrl@kvack.org> wrote:
> > On Sat, Jan 28, 2006 at 01:28:20AM +0100, Eric Dumazet wrote:
> > > We might use atomic_long_t only (and no spinlocks)
> > > Something like this ?
> >
> > Erk, complex and slow...  Try using local_t instead, which is
> > substantially cheaper on the P4 as it doesn't use the lock prefix and act
> > as a memory barrier.  See asm/local.h.
>
> local_t isn't much use until we get rid of asm-generic/local.h.  Bloaty,
> racy with nested interrupts.

It is just implemented wrong. It should use 
local_irq_save()/local_irq_restore() instead. But my bigger problem
with local_t is these few architectures (IA64, PPC64) who implement it 
with atomic_t. This means we can't replace local statistics counters
with local_t because it would be regression for them. I haven't done the
benchmarks yet, but I suspect both IA64 and PPC64 really should
just turn off interrupts.

-Andi

^ permalink raw reply

* Re: [patch 3/4] net: Percpufy frequently used variables -- proto.sockets_allocated
From: Eric Dumazet @ 2006-01-29  6:54 UTC (permalink / raw)
  To: Benjamin LaHaise
  Cc: Andrew Morton, kiran, davem, linux-kernel, shai, netdev, pravins
In-Reply-To: <20060129004459.GA24099@kvack.org>

Benjamin LaHaise a écrit :
> On Sat, Jan 28, 2006 at 01:28:20AM +0100, Eric Dumazet wrote:
>> We might use atomic_long_t only (and no spinlocks)
>> Something like this ?
> 
> Erk, complex and slow...  Try using local_t instead, which is substantially 
> cheaper on the P4 as it doesn't use the lock prefix and act as a memory 
> barrier.  See asm/local.h.
> 

Well, I think that might be doable, maybe RCU magic ?

1) local_t are not that nice on all archs.

2) The consolidation phase (summing all the cpus local offset to consolidate 
the central counter) might be more difficult to do (we would need kind of 2 
counters per cpu, and a index that can be changed by the cpu that wants a 
consolidation (still 'expensive'))

struct cpu_offset {
	local_t   offset[2];
	};

struct percpu_counter {
	atomic_long_t count;
	unsigned int offidx;
	spinlock_t   lock; /* to guard offidx changes */
	cpu_offset *counters;
};

void percpu_counter_mod(struct percpu_counter *fbc, long amount)
{
         long val;
	struct cpu_offset *cp;
	local_t *l;

	cp = per_cpu_ptr(fbc->counters, get_cpu());
	l = &cp[fbc->offidx];

         local_add(amount, l);
	val = local_read(l);
	if (new >= FBC_BATCH || new <= -FBC_BATCH) {
                 local_set(l, 0);
                 atomic_long_add(val, &fbc->count);
	}
	put_cpu();
}

long percpu_counter_read_accurate(struct percpu_counter *fbc)
{
	long res = 0, val;
	int cpu;
	struct cpu_offset *cp;
	local_t *l;

	spin_lock(&fbc->lock);
	idx = fbc->offidx;
	fbc->offidx ^= 1;
	mb();
	/*
	 * FIXME :
	 *	must 'wait' other cpus dont touch anymore their old local_t
	 */
	for_each_cpu(cpu) {
		cp = per_cpu_ptr(fbc->counters, cpu);
		l = &cp[idx];
		val = local_read(l);
		/* dont dirty alien cache line if not necessary */
		if (val)
			local_set(l, 0);
		res += val;
	}
	spin_unlock(&fbc->lock);
         atomic_long_add(res, &fbc->count);
         return atomic_long_read(&fbc->count);
}



3) Are the locked ops so expensive if done on a cache line that is mostly in 
exclusive state in cpu cache ?

Thank you
Eric

^ permalink raw reply

* Re: [GIT PULL] bcm43xx update
From: Michael Buesch @ 2006-01-29 10:38 UTC (permalink / raw)
  To: John W. Linville
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, bcm43xx-dev-0fE9KPoRgkgATYTw5x5z8w
In-Reply-To: <200601271842.54347.mbuesch-KuiJ5kEpwI6ELgA04lAiVw@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 480 bytes --]

On Friday 27 January 2006 18:42, you wrote:
> Please do a
> git pull git://bu3sch.de/bcm43xx.git master-upstream
> to pull the bcm43xx-softmac branch.
> 
> Please do a
> git pull git://bu3sch.de/bcm43xx.git dscape-upstream
> to pull the bcm43xx-dscape branch.

Did you already pull? I did not see it in your git logs.
I have to do some maintainance work on my public repository
and I am waiting for your pull, before I shut down the server.

-- 
Greetings Michael.

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* [PATH] acxsm: Move WEP code into softmac
From: Carlos Martín @ 2006-01-29 14:26 UTC (permalink / raw)
  To: acx100-devel; +Cc: netdev


[-- Attachment #1.1: Type: text/plain, Size: 650 bytes --]

Hi,

 This patch moves the WEP handling code to use the softmac layer and 
implements acx_e_ieee80211_set_security(), based on the rt2x00 project's one.

 I do have a couple of questions though:

1) adev->wep_restricted = 0 is the same as an open auth system, and 
adev->wep_restricted = 1 is the same as having a shared key auth system, 
right?

2) What is the purpose of the index field in key_struct_t? I've assumed it is 
the same as adev->wep_current_index, but I'm not sure this is correct.

   cmn
-- 
Carlos Martín       http://www.cmartin.tk

"Erdbeben? Sicherlich etwas, das mit Erdberen zu tun hat." -- me, paraphrased

[-- Attachment #1.2: acxsm-move-wep-into-softmac.patch --]
[-- Type: text/x-diff, Size: 13570 bytes --]

diff -urp acxsm-0123.orig/acx_struct.h acxsm-0123/acx_struct.h
--- acxsm-0123.orig/acx_struct.h	2006-01-16 15:25:41.000000000 +0100
+++ acxsm-0123/acx_struct.h	2006-01-29 14:06:17.000000000 +0100
@@ -603,31 +603,6 @@ typedef struct fw_ver {
 
 #define FW_ID_SIZE 20
 
-
-/*--- WEP stuff --------------------------------------------------------------*/
-#define DOT11_MAX_DEFAULT_WEP_KEYS	4
-
-/* non-firmware struct, no packing necessary */
-typedef struct wep_key {
-	size_t	size; /* most often used member first */
-	u8	index;
-	u8	key[29];
-	u16	strange_filler;
-} wep_key_t;			/* size = 264 bytes (33*8) */
-/* FIXME: We don't have size 264! Or is there 2 bytes beyond the key
- * (strange_filler)? */
-
-/* non-firmware struct, no packing necessary */
-typedef struct key_struct {
-	u8	addr[ETH_ALEN];	/* 0x00 */
-	u16	filler1;	/* 0x06 */
-	u32	filler2;	/* 0x08 */
-	u32	index;		/* 0x0c */
-	u16	len;		/* 0x10 */
-	u8	key[29];	/* 0x12; is this long enough??? */
-} key_struct_t;			/* size = 276. FIXME: where is the remaining space?? */
-
-
 /*--- Client (peer) info -----------------------------------------------------*/
 /* adev->sta_list[] is used for:
 ** accumulating and processing of scan results
@@ -1286,14 +1261,6 @@ struct acx_device {
 	u8		rate_supported_len;
 	u8		rate_supported[13];
 
-	/*** Encryption settings (WEP) ***/
-	u32		auth_alg;		/* used in transmit_authen1 */
-	u8		wep_enabled;
-	u8		wep_restricted;
-	u8		wep_current_index;
-	wep_key_t	wep_keys[DOT11_MAX_DEFAULT_WEP_KEYS];	/* the default WEP keys */
-	key_struct_t	wep_key_struct[10];
-
 	/*** Unknown ***/
 	u8		dtim_interval;
 
diff -urp acxsm-0123.orig/common.c acxsm-0123/common.c
--- acxsm-0123.orig/common.c	2006-01-19 11:28:23.000000000 +0100
+++ acxsm-0123/common.c	2006-01-29 14:59:46.000000000 +0100
@@ -1137,8 +1137,8 @@ acx_s_proc_diag_output(char *buf, acx_de
 		"WEP ena %d, restricted %d, idx %d\n",
 		adev->essid, adev->essid_active, (int)adev->essid_len,
 		adev->essid_for_assoc, adev->nick,
-		adev->wep_enabled, adev->wep_restricted,
-		adev->wep_current_index);
+		adev->ieee->sec.enabled, adev->ieee->sec.auth_mode,
+		adev->ieee->sec.active_key);
 	p += sprintf(p, "dev_addr  "MACSTR"\n", MAC(adev->dev_addr));
 	p += sprintf(p, "bssid     "MACSTR"\n", MAC(adev->bssid));
 	p += sprintf(p, "ap_filter "MACSTR"\n", MAC(adev->ap));
@@ -2143,7 +2143,7 @@ acx_s_set_defaults(acx_device_t *adev)
 	/* reported to break scanning: adev->scan_probe_delay = adev->cfgopt_probe_delay; */
 	adev->scan_rate = ACX_SCAN_RATE_1;
 
-	adev->auth_alg = WLAN_AUTH_ALG_OPENSYSTEM;
+	adev->ieee->sec.auth_mode = WLAN_AUTH_OPEN;
 	adev->preamble_mode = 2; /* auto */
 	adev->listen_interval = 100;
 	adev->beacon_interval = DEFAULT_BEACON_INTERVAL;
@@ -5435,14 +5435,14 @@ acx100_s_set_wepkey(acx_device_t *adev)
 	ie_dot11WEPDefaultKey_t dk;
 	int i;
 
-	for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
-		if (adev->wep_keys[i].size != 0) {
+	for (i = 0; i < WEP_KEYS; i++) {
+		if (adev->ieee->sec.key_sizes[i] != 0) {
 			log(L_INIT, "setting WEP key: %d with "
-				"total size: %d\n", i, (int) adev->wep_keys[i].size);
+				"total size: %d\n", i, (int) adev->ieee->sec.key_sizes[i]);
 			dk.action = 1;
-			dk.keySize = adev->wep_keys[i].size;
+			dk.keySize = adev->ieee->sec.key_sizes[i];
 			dk.defaultKeyNum = i;
-			memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
+			memcpy(dk.key, adev->ieee->sec.keys[i], dk.keySize);
 			acx_s_configure(adev, &dk, ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE);
 		}
 	}
@@ -5454,20 +5454,20 @@ acx111_s_set_wepkey(acx_device_t *adev)
 	acx111WEPDefaultKey_t dk;
 	int i;
 
-	for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) {
-		if (adev->wep_keys[i].size != 0) {
+	for (i = 0; i < WEP_KEYS; i++) {
+		if (adev->ieee->sec.key_sizes[i] != 0) {
 			log(L_INIT, "setting WEP key: %d with "
-				"total size: %d\n", i, (int) adev->wep_keys[i].size);
+				"total size: %d\n", i, (int) adev->ieee->sec.key_sizes[i]);
 			memset(&dk, 0, sizeof(dk));
 			dk.action = cpu_to_le16(1); /* "add key"; yes, that's a 16bit value */
-			dk.keySize = adev->wep_keys[i].size;
+			dk.keySize = adev->ieee->sec.key_sizes[i];
 
 			/* are these two lines necessary? */
 			dk.type = 0;              /* default WEP key */
 			dk.index = 0;             /* ignored when setting default key */
 
 			dk.defaultKeyNum = i;
-			memcpy(dk.key, adev->wep_keys[i].key, dk.keySize);
+			memcpy(dk.key, adev->ieee->sec.keys[i], dk.keySize);
 			acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &dk, sizeof(dk));
 		}
 	}
@@ -5514,7 +5514,7 @@ acx100_s_init_wep(acx_device_t *adev)
 	}
 
 	/* let's choose maximum setting: 4 default keys, plus 10 other keys: */
-	options.NumKeys = cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
+	options.NumKeys = cpu_to_le16(WEP_KEYS + 10);
 	options.WEPOption = 0x00;
 
 	log(L_ASSOC, "%s: writing WEP options\n", __func__);
@@ -5522,10 +5522,10 @@ acx100_s_init_wep(acx_device_t *adev)
 
 	acx100_s_set_wepkey(adev);
 
-	if (adev->wep_keys[adev->wep_current_index].size != 0) {
+	if (adev->ieee->sec.key_sizes[adev->ieee->sec.active_key] != 0) {
 		log(L_ASSOC, "setting active default WEP key number: %d\n",
-				adev->wep_current_index);
-		dk.KeyID = adev->wep_current_index;
+				adev->ieee->sec.active_key);
+		dk.KeyID = adev->ieee->sec.active_key;
 		acx_s_configure(adev, &dk, ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET); /* 0x1010 */
 	}
 	/* FIXME!!! wep_key_struct is filled nowhere! But adev
@@ -6581,7 +6581,7 @@ acx_s_update_card_settings(acx_device_t 
 
 		acx_s_set_wepkey(adev);
 
-		dkey.KeyID = adev->wep_current_index;
+		dkey.KeyID = adev->ieee->sec.active_key;
 		log(L_INIT, "setting WEP key %u as default\n", dkey.KeyID);
 		acx_s_configure(adev, &dkey, ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET);
 #ifdef DEBUG_WEP
@@ -6602,7 +6602,7 @@ acx_s_update_card_settings(acx_device_t 
 
 			/* let's choose maximum setting: 4 default keys,
 			 * plus 10 other keys: */
-			options.NumKeys = cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10);
+			options.NumKeys = cpu_to_le16(WEP_KEYS + 10);
 			/* don't decrypt default key only,
 			 * don't override decryption: */
 			options.WEPOption = 0;
@@ -6905,7 +6905,7 @@ acx_update_capabilities(acx_device_t *ad
 	/* other types of stations do not emit beacons */
 	}
 
-	if (adev->wep_restricted) {
+	if (adev->ieee->sec.auth_mode == WLAN_AUTH_SHARED_KEY) {
 		SET_BIT(cap, WF_MGMT_CAP_PRIVACY);
 	}
 	if (adev->cfgopt_dot11ShortPreambleOption) {
@@ -7135,10 +7135,74 @@ module_exit(acx_e_cleanup_module)
 
 //SM
 void
-acx_e_ieee80211_set_security(struct net_device *dev,
+acx_e_ieee80211_set_security(struct net_device *ndev,
 		struct ieee80211_security *sec)
 {
-//todo
+/* Shamelessly copied from the rt2x00 project. */
+	acx_device_t *adev = ndev2adev(ndev);
+	unsigned long flags;
+	int i;
+
+	acx_sem_lock(adev);
+	acx_lock(adev, flags);
+
+	for (i = 0; i < WEP_KEYS; ++i) {
+		/* This gives us the flag for the 4 WEP keys. */
+		if (sec->flags & (1 << i)) {
+			adev->ieee->sec.encode_alg[i] = sec->encode_alg[i];
+			adev->ieee->sec.key_sizes[i] = sec->key_sizes[i];
+
+			if (sec->key_sizes[i] != 0) {
+				memcpy(adev->ieee->sec.keys[i], sec->keys[i],
+				       sec->key_sizes[i]);
+				/* Make sure WEP flag is set. */
+				adev->ieee->sec.flags |= (1 << i);
+			} else if (sec->level != SEC_LEVEL_1)
+				/* Make sure WEP flag isn't set. */
+				adev->ieee->sec.flags &= ~(1 << i);
+		}
+		SET_BIT(adev->set_mask, SET_WEP_OPTIONS);
+	}
+
+	if (sec->flags & SEC_ACTIVE_KEY) {
+		/* Check the key number is valid. */
+		if (sec->active_key < WEP_KEYS) {
+			adev->ieee->sec.active_key = sec->active_key;
+			adev->ieee->sec.flags |= SEC_ACTIVE_KEY;
+		} else
+			adev->ieee->sec.flags &= ~SEC_ACTIVE_KEY;
+		
+	} else
+		adev->ieee->sec.flags &= ~SEC_ACTIVE_KEY;
+
+	if (sec->flags & SEC_AUTH_MODE) {
+		adev->ieee->sec.auth_mode = sec->auth_mode;
+		adev->ieee->sec.flags |= SEC_AUTH_MODE;
+		SET_BIT(adev->set_mask, SET_WEP_OPTIONS);
+	}
+
+	if (sec->flags & SEC_ENCRYPT) {
+		adev->ieee->sec.encrypt = sec->encrypt;
+		adev->ieee->sec.flags |= SEC_ENCRYPT;
+		SET_BIT(adev->set_mask, GETSET_WEP);
+	}
+
+	if (sec->flags & SEC_ENABLED) {
+		adev->ieee->sec.enabled = sec->enabled;
+		adev->ieee->sec.flags |= SEC_ENABLED;
+		SET_BIT(adev->set_mask, GETSET_WEP);
+	}
+
+	if (sec->flags & SEC_LEVEL) {
+		adev->ieee->sec.level = sec->level;
+		adev->ieee->sec.flags |= SEC_LEVEL;
+		SET_BIT(adev->set_mask, GETSET_WEP);
+	}
+	
+	acx_unlock(adev, flags);
+	acx_sem_unlock(adev);
+
+	acx_s_update_card_settings(adev);
 }
 
 
diff -urp acxsm-0123.orig/ioctl.c acxsm-0123/ioctl.c
--- acxsm-0123.orig/ioctl.c	2006-01-16 15:25:41.000000000 +0100
+++ acxsm-0123/ioctl.c	2006-01-29 14:07:08.000000000 +0100
@@ -1024,7 +1024,7 @@ acx_ioctl_set_encode(
 	if (dwrq->length > 0) {
 		/* if index is 0 or invalid, use default key */
 		if ((index < 0) || (index > 3))
-			index = (int)adev->wep_current_index;
+			index = (int)adev->ieee->sec.active_key;
 
 		if (0 == (dwrq->flags & IW_ENCODE_NOKEY)) {
 			if (dwrq->length > 29)
@@ -1032,26 +1032,26 @@ acx_ioctl_set_encode(
 
 			if (dwrq->length > 13) {
 				/* 29*8 == 232, WEP256 */
-				adev->wep_keys[index].size = 29;
+				adev->ieee->sec.key_sizes[index] = 29;
 			} else if (dwrq->length > 5) {
 				/* 13*8 == 104bit, WEP128 */
-				adev->wep_keys[index].size = 13;
+				adev->ieee->sec.key_sizes[index] = 13;
 			} else if (dwrq->length > 0) {
 				/* 5*8 == 40bit, WEP64 */
-				adev->wep_keys[index].size = 5;
+				adev->ieee->sec.key_sizes[index] = 5;
 			} else {
 				/* disable key */
-				adev->wep_keys[index].size = 0;
+				adev->ieee->sec.key_sizes[index] = 0;
 			}
 
-			memset(adev->wep_keys[index].key, 0,
-				sizeof(adev->wep_keys[index].key));
-			memcpy(adev->wep_keys[index].key, extra, dwrq->length);
+			memset(adev->ieee->sec.keys[index], 0,
+				sizeof(adev->ieee->sec.keys[index]));
+			memcpy(adev->ieee->sec.keys[index], extra, dwrq->length);
 		}
 	} else {
 		/* set transmit key */
 		if ((index >= 0) && (index <= 3))
-			adev->wep_current_index = index;
+			adev->ieee->sec.active_key = index;
 		else if (0 == (dwrq->flags & IW_ENCODE_MODE)) {
 			/* complain if we were not just setting
 			 * the key mode */
@@ -1060,15 +1060,13 @@ acx_ioctl_set_encode(
 		}
 	}
 
-	adev->wep_enabled = !(dwrq->flags & IW_ENCODE_DISABLED);
+	adev->ieee->sec.enabled = !(dwrq->flags & IW_ENCODE_DISABLED);
 
 	if (dwrq->flags & IW_ENCODE_OPEN) {
-		adev->auth_alg = WLAN_AUTH_ALG_OPENSYSTEM;
-		adev->wep_restricted = 0;
+		adev->ieee->sec.auth_mode = WLAN_AUTH_OPEN;
 
 	} else if (dwrq->flags & IW_ENCODE_RESTRICTED) {
-		adev->auth_alg = WLAN_AUTH_ALG_SHAREDKEY;
-		adev->wep_restricted = 1;
+	  adev->ieee->sec.auth_mode = WLAN_AUTH_SHARED_KEY;
 	}
 
 	/* set flag to make sure the card WEP settings get updated */
@@ -1078,11 +1076,11 @@ acx_ioctl_set_encode(
 		dwrq->length, extra, dwrq->flags);
 
 	for (index = 0; index <= 3; index++) {
-		if (adev->wep_keys[index].size) {
+		if (adev->ieee->sec.key_sizes[index]) {
 			log(L_IOCTL,	"index=%d, size=%d, key at 0x%p\n",
-				adev->wep_keys[index].index,
-				(int) adev->wep_keys[index].size,
-				adev->wep_keys[index].key);
+				adev->ieee->sec.active_key,
+				(int) adev->ieee->sec.key_sizes[index],
+				adev->ieee->sec.keys[index]);
 		}
 	}
 	result = -EINPROGRESS;
@@ -1111,18 +1109,18 @@ acx_ioctl_get_encode(
 
 	FN_ENTER;
 
-	if (adev->wep_enabled == 0) {
+	if (adev->ieee->sec.enabled == 0) {
 		dwrq->flags = IW_ENCODE_DISABLED;
 	} else {
 		if ((index < 0) || (index > 3))
-			index = (int)adev->wep_current_index;
+			index = (int)adev->ieee->sec.active_key;
 
-		dwrq->flags = (adev->wep_restricted == 1) ?
+		dwrq->flags = (adev->ieee->sec.auth_mode == WLAN_AUTH_SHARED_KEY) ?
 				IW_ENCODE_RESTRICTED : IW_ENCODE_OPEN;
-		dwrq->length = adev->wep_keys[index].size;
+		dwrq->length = adev->ieee->sec.key_sizes[index];
 
-		memcpy(extra, adev->wep_keys[index].key,
-			      adev->wep_keys[index].size);
+		memcpy(extra, adev->ieee->sec.keys[index],
+			      adev->ieee->sec.key_sizes[index]);
 	}
 
 	/* set the current index */
diff -urp acxsm-0123.orig/pci.c acxsm-0123/pci.c
--- acxsm-0123.orig/pci.c	2006-01-22 16:48:35.000000000 +0100
+++ acxsm-0123/pci.c	2006-01-29 15:23:51.000000000 +0100
@@ -1641,6 +1641,10 @@ acxpci_e_probe(struct pci_dev *pdev, con
 	adev->softmac = ieee80211_priv(ndev);
 	adev->softmac->set_channel = acx_e_ieee80211_set_chan;
 
+	adev->ieee->sec.encrypt = 0;
+	adev->ieee->sec.enabled = 0;
+	adev->ieee->sec.auth_mode = WLAN_AUTH_OPEN;
+
 #ifdef NONESSENTIAL_FEATURES
 	acx_show_card_eeprom_id(adev);
 #endif /* NONESSENTIAL_FEATURES */
diff -urp acxsm-0123.orig/usb.c acxsm-0123/usb.c
--- acxsm-0123.orig/usb.c	2006-01-15 23:55:25.000000000 +0100
+++ acxsm-0123/usb.c	2006-01-28 20:59:40.000000000 +0100
@@ -677,6 +677,10 @@ acxusb_e_probe(struct usb_interface *int
 	adev->softmac = ieee80211_priv(ndev);
 	adev->softmac->set_channel = acx_e_ieee80211_set_chan;
 
+	adev->ieee->sec.enabled = 0;
+	adev->ieee->sec.encrypt = 0;
+	adev->ieee->sec.auth_mode = WLAN_AUTH_OPEN;
+
 	/* Check that this is really the hardware we know about.
 	** If not sure, at least notify the user that he
 	** may be in trouble...

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: [patch 3/4] net: Percpufy frequently used variables -- proto.sockets_allocated
From: Benjamin LaHaise @ 2006-01-29 19:52 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Andrew Morton, kiran, davem, linux-kernel, shai, netdev, pravins
In-Reply-To: <43DC6691.9000001@cosmosbay.com>

On Sun, Jan 29, 2006 at 07:54:09AM +0100, Eric Dumazet wrote:
> Well, I think that might be doable, maybe RCU magic ?
> 
> 1) local_t are not that nice on all archs.

It is for the users that matter, and the hooks are there if someone finds 
it to be a performance problem.

> 2) The consolidation phase (summing all the cpus local offset to 
> consolidate the central counter) might be more difficult to do (we would 
> need kind of 2 counters per cpu, and a index that can be changed by the cpu 
> that wants a consolidation (still 'expensive'))

For the vast majority of these sorts of statistics counters, we don't 
need 100% accurate counts.  And I think it should be possible to choose 
between a lightweight implementation and the expensive implementation.  
On a chip like the Core Duo the cost of bouncing between the two cores 
is minimal, so all the extra code and data is a waste.

> 3) Are the locked ops so expensive if done on a cache line that is mostly 
> in exclusive state in cpu cache ?

Yes.  What happens on the P4 is that it forces outstanding memory 
transactions in the reorder buffer to be flushed so that the memory barrier 
semantics of the lock prefix are observed.  This can take a long time as
there can be over a hundred instructions in flight.

		-ben
-- 
"Ladies and gentlemen, I'm sorry to interrupt, but the police are here 
and they've asked us to stop the party."  Don't Email: <dont@kvack.org>.

^ permalink raw reply

* [PATCH 4/4]  pktgen: Fix Initialization fail leak.
From: Luiz Fernando Capitulino @ 2006-01-30  1:21 UTC (permalink / raw)
  To: davem; +Cc: lkml, netdev, robert.olsson


 Even if pktgen's thread initialization fails for all CPUs, the module
will be successfully loaded.

 This patch changes that behaivor, by returning error on module load time,
and also freeing all the resources allocated. It also prints a warning if a
thread initialization has failed.

Signed-off-by: Luiz Capitulino <lcapitulino@mandriva.com.br>


---

 net/core/pktgen.c |   15 ++++++++++++++-
 1 files changed, 14 insertions(+), 1 deletions(-)

909df2e921dabd2f43f80f4fe067bf3b86fbc3cd
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index af310e5..3806068 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -3136,11 +3136,24 @@ static int __init pg_init(void)
 	register_netdevice_notifier(&pktgen_notifier_block);
 
 	for_each_online_cpu(cpu) {
+		int err;
 		char buf[30];
 
 		sprintf(buf, "kpktgend_%i", cpu);
-		pktgen_create_thread(buf, cpu);
+		err = pktgen_create_thread(buf, cpu);
+		if (err)
+			printk("pktgen: WARNING: Cannot create thread for cpu %d (%d)\n",
+					cpu, err);
 	}
+
+	if (list_empty(&pktgen_threads)) {
+		printk("pktgen: ERROR: Initialization failed for all threads\n");
+		unregister_netdevice_notifier(&pktgen_notifier_block);
+		remove_proc_entry(PGCTRL, pg_proc_dir);
+		proc_net_remove(PG_PROC_DIR);
+		return -ENODEV;
+	}
+
 	return 0;
 }
 
-- 
1.1.5.g3480


-- 
Luiz Fernando N. Capitulino

^ permalink raw reply related

* [PATCH 3/4]  pktgen: Fix kernel_thread() fail leak.
From: Luiz Fernando Capitulino @ 2006-01-30  1:21 UTC (permalink / raw)
  To: davem; +Cc: lkml, netdev, robert.olsson


 Leak fix: free all the alocated resources if kernel_thread() call fails.

Signed-off-by: Luiz Capitulino <lcapitulino@mandriva.com.br>


---

 net/core/pktgen.c |   11 +++++++++--
 1 files changed, 9 insertions(+), 2 deletions(-)

59115e7981073430cfcaaaabcde20840ec926cca
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index b9dea09..af310e5 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -3002,6 +3002,7 @@ static struct pktgen_thread *__init pktg
 
 static int __init pktgen_create_thread(const char *name, int cpu)
 {
+	int err;
 	struct pktgen_thread *t = NULL;
 	struct proc_dir_entry *pe;
 
@@ -3040,9 +3041,15 @@ static int __init pktgen_create_thread(c
 
 	t->removed = 0;
 
-	if (kernel_thread((void *)pktgen_thread_worker, (void *)t,
-			  CLONE_FS | CLONE_FILES | CLONE_SIGHAND) < 0)
+	err = kernel_thread((void *)pktgen_thread_worker, (void *)t,
+			  CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
+	if (err < 0) {
 		printk("pktgen: kernel_thread() failed for cpu %d\n", t->cpu);
+		remove_proc_entry(t->name, pg_proc_dir);
+		list_del(&t->th_list);
+		kfree(t);
+		return err;
+	}
 
 	return 0;
 }
-- 
1.1.5.g3480


-- 
Luiz Fernando N. Capitulino

^ permalink raw reply related

* [PATCH 2/4]  pktgen: Ports thread list to Kernel list implementation.
From: Luiz Fernando Capitulino @ 2006-01-30  1:21 UTC (permalink / raw)
  To: davem; +Cc: lkml, netdev, robert.olsson


 Ports the thread list to use the Linux Kernel linked list implementation.
The final result is a simpler and smaller code.

 Note that I'm adding a new member in the struct pktgen_thread called
'removed'. The reason is that I didn't find a better wait condition to be
used in the place of the replaced one. Suggestions are very welcome.

Signed-off-by: Luiz Capitulino <lcapitulino@mandriva.com.br>


---

 net/core/pktgen.c |   96 +++++++++++++++++++++++------------------------------
 1 files changed, 41 insertions(+), 55 deletions(-)

3679f7d860ed28c86f0c8e1d6c1b4d9ee1e716d7
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index a6a45b9..b9dea09 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -125,6 +125,7 @@
 #include <linux/capability.h>
 #include <linux/delay.h>
 #include <linux/timer.h>
+#include <linux/list.h>
 #include <linux/init.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
@@ -327,7 +328,8 @@ struct pktgen_hdr {
 struct pktgen_thread {
 	spinlock_t if_lock;
 	struct pktgen_dev *if_list;	/* All device here */
-	struct pktgen_thread *next;
+	struct list_head th_list;
+	int removed;
 	char name[32];
 	char result[512];
 	u32 max_before_softirq;	/* We'll call do_softirq to prevent starvation. */
@@ -489,7 +491,7 @@ static int pg_clone_skb_d;
 static int debug;
 
 static DECLARE_MUTEX(pktgen_sem);
-static struct pktgen_thread *pktgen_threads = NULL;
+static LIST_HEAD(pktgen_threads);
 
 static struct notifier_block pktgen_notifier_block = {
 	.notifier_call = pktgen_device_event,
@@ -1522,9 +1524,7 @@ static struct pktgen_dev *__pktgen_NN_th
 	struct pktgen_thread *t;
 	struct pktgen_dev *pkt_dev = NULL;
 
-	t = pktgen_threads;
-
-	while (t) {
+	list_for_each_entry(t, &pktgen_threads, th_list) {
 		pkt_dev = pktgen_find_dev(t, ifname);
 		if (pkt_dev) {
 			if (remove) {
@@ -1534,7 +1534,6 @@ static struct pktgen_dev *__pktgen_NN_th
 			}
 			break;
 		}
-		t = t->next;
 	}
 	return pkt_dev;
 }
@@ -2422,15 +2421,15 @@ static void pktgen_run(struct pktgen_thr
 
 static void pktgen_stop_all_threads_ifs(void)
 {
-	struct pktgen_thread *t = pktgen_threads;
+	struct pktgen_thread *t;
 
 	PG_DEBUG(printk("pktgen: entering pktgen_stop_all_threads.\n"));
 
 	thread_lock();
-	while (t) {
+
+	list_for_each_entry(t, &pktgen_threads, th_list)
 		pktgen_stop(t);
-		t = t->next;
-	}
+
 	thread_unlock();
 }
 
@@ -2472,40 +2471,36 @@ signal:
 
 static int pktgen_wait_all_threads_run(void)
 {
-	struct pktgen_thread *t = pktgen_threads;
+	struct pktgen_thread *t;
 	int sig = 1;
 
-	while (t) {
+	thread_lock();
+
+	list_for_each_entry(t, &pktgen_threads, th_list) {
 		sig = pktgen_wait_thread_run(t);
 		if (sig == 0)
 			break;
-		thread_lock();
-		t = t->next;
-		thread_unlock();
 	}
-	if (sig == 0) {
-		thread_lock();
-		while (t) {
+
+	if (sig == 0)
+		list_for_each_entry(t, &pktgen_threads, th_list)
 			t->control |= (T_STOP);
-			t = t->next;
-		}
-		thread_unlock();
-	}
+
+	thread_unlock();
 	return sig;
 }
 
 static void pktgen_run_all_threads(void)
 {
-	struct pktgen_thread *t = pktgen_threads;
+	struct pktgen_thread *t;
 
 	PG_DEBUG(printk("pktgen: entering pktgen_run_all_threads.\n"));
 
 	thread_lock();
 
-	while (t) {
+	list_for_each_entry(t, &pktgen_threads, th_list)
 		t->control |= (T_RUN);
-		t = t->next;
-	}
+
 	thread_unlock();
 
 	schedule_timeout_interruptible(msecs_to_jiffies(125));	/* Propagate thread->control  */
@@ -2625,24 +2620,12 @@ static void pktgen_rem_thread(struct pkt
 {
 	/* Remove from the thread list */
 
-	struct pktgen_thread *tmp = pktgen_threads;
-
 	remove_proc_entry(t->name, pg_proc_dir);
 
 	thread_lock();
 
-	if (tmp == t)
-		pktgen_threads = tmp->next;
-	else {
-		while (tmp) {
-			if (tmp->next == t) {
-				tmp->next = t->next;
-				t->next = NULL;
-				break;
-			}
-			tmp = tmp->next;
-		}
-	}
+	list_del(&t->th_list);
+
 	thread_unlock();
 }
 
@@ -2890,6 +2873,8 @@ static void pktgen_thread_worker(struct 
 
 	PG_DEBUG(printk("pktgen: %s removing thread.\n", t->name));
 	pktgen_rem_thread(t);
+
+	t->removed = 1;
 }
 
 static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t,
@@ -3001,19 +2986,18 @@ static int pktgen_add_device(struct pktg
 
 static struct pktgen_thread *__init pktgen_find_thread(const char *name)
 {
-	struct pktgen_thread *t = NULL;
+	struct pktgen_thread *t;
 
 	thread_lock();
 
-	t = pktgen_threads;
-	while (t) {
-		if (strcmp(t->name, name) == 0)
-			break;
+	list_for_each_entry(t, &pktgen_threads, th_list)
+		if (strcmp(t->name, name) == 0) {
+			thread_unlock();
+			return t;
+		}
 
-		t = t->next;
-	}
 	thread_unlock();
-	return t;
+	return NULL;
 }
 
 static int __init pktgen_create_thread(const char *name, int cpu)
@@ -3052,8 +3036,9 @@ static int __init pktgen_create_thread(c
 	pe->proc_fops = &pktgen_thread_fops;
 	pe->data = t;
 
-	t->next = pktgen_threads;
-	pktgen_threads = t;
+	list_add_tail(&t->th_list, &pktgen_threads);
+
+	t->removed = 0;
 
 	if (kernel_thread((void *)pktgen_thread_worker, (void *)t,
 			  CLONE_FS | CLONE_FILES | CLONE_SIGHAND) < 0)
@@ -3154,17 +3139,18 @@ static int __init pg_init(void)
 
 static void __exit pg_cleanup(void)
 {
+	struct pktgen_thread *t;
+	struct list_head *q, *n;
 	wait_queue_head_t queue;
 	init_waitqueue_head(&queue);
 
 	/* Stop all interfaces & threads */
 
-	while (pktgen_threads) {
-		struct pktgen_thread *t = pktgen_threads;
-		pktgen_threads->control |= (T_TERMINATE);
+	list_for_each_safe(q, n, &pktgen_threads) {
+		t = list_entry(q, struct pktgen_thread, th_list);
+		t->control |= (T_TERMINATE);
 
-		wait_event_interruptible_timeout(queue, (t != pktgen_threads),
-						 HZ);
+		wait_event_interruptible_timeout(queue, (t->removed == 1), HZ);
 	}
 
 	/* Un-register us from receiving netdevice events */
-- 
1.1.5.g3480


-- 
Luiz Fernando N. Capitulino

^ permalink raw reply related

* [PATCH 1/4]  pktgen: Lindent run.
From: Luiz Fernando Capitulino @ 2006-01-30  1:21 UTC (permalink / raw)
  To: davem; +Cc: lkml, netdev, robert.olsson


 This patch is not in-lined because it's 120K bytes long, you can found it at:

http://www.cpu.eti.br/patches/0001-pktgen-Lindent-run.patch

-- 
Luiz Fernando N. Capitulino

^ permalink raw reply

* [PATCH 0/4] - pktgen: refinements and small fixes (V2).
From: Luiz Fernando Capitulino @ 2006-01-30  1:23 UTC (permalink / raw)
  To: davem; +Cc: lkml, netdev, robert.olsson


 Hi!

 I'm sending again the following patches for pktgen:

[PATCH 1/4]  pktgen: Lindent run.
[PATCH 2/4]  pktgen: Ports thread list to Kernel list implementation.
[PATCH 3/4]  pktgen: Fix kernel_thread() fail leak.
[PATCH 4/4]  pktgen: Fix Initialization fail leak.

 The changes from V1 are:

 1. More fixes made by hand after Lindent run
 2. Re-diffed agains't Dave's net-2.6.17 tree
 
  All the patches were tested with QEMU, emulating a machine with 4 CPUs
and 4 ethernet cards.

-- 
Luiz Fernando N. Capitulino

^ permalink raw reply

* net/tipc/bcast.c:tipc_bcbearer_send() stack usage
From: Adrian Bunk @ 2006-01-30  2:47 UTC (permalink / raw)
  To: per.liden, jon.maloy, allan.stephens
  Cc: tipc-discussion, netdev, linux-kernel

>From net/tipc/bcast.c:

<--  snip  -->

...
int tipc_bcbearer_send(struct sk_buff *buf,
                       struct tipc_bearer *unused1,
                       struct tipc_media_addr *unused2)
{
        static int send_count = 0;

        struct node_map remains;
        struct node_map remains_new;
...

<--  snip  -->


You've just allocated 2*516 Bytes for the two structs from a stack that 
might only be 4 kB altogether.

cu
Adrian

-- 

       "Is there not promise of rain?" Ling Tan asked suddenly out
        of the darkness. There had been need of rain for many days.
       "Only a promise," Lao Er said.
                                       Pearl S. Buck - Dragon Seed

^ permalink raw reply

* Re: [PATH] acxsm: Move WEP code into softmac
From: Denis Vlasenko @ 2006-01-30  7:18 UTC (permalink / raw)
  To: acx100-devel; +Cc: Carlos Martín, netdev
In-Reply-To: <200601291526.09333.carlos@cmartin.tk>

On Sunday 29 January 2006 16:26, Carlos Martín wrote:
> Hi,
> 
>  This patch moves the WEP handling code to use the softmac layer and 
> implements acx_e_ieee80211_set_security(), based on the rt2x00 project's one.

Applied, thanks!
 
>  I do have a couple of questions though:
> 
> 1) adev->wep_restricted = 0 is the same as an open auth system, and 
> adev->wep_restricted = 1 is the same as having a shared key auth system, 
> right?
> 
> 2) What is the purpose of the index field in key_struct_t? I've assumed it is 
> the same as adev->wep_current_index, but I'm not sure this is correct.

To be honest, I did not pay much attention to inner WEP workings...
--
vda


-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid\x103432&bid#0486&dat\x121642

^ permalink raw reply

* [PATCH 0/4] - pktgen: refinements and small fixes (V2).
From: Robert Olsson @ 2006-01-30 11:18 UTC (permalink / raw)
  To: davem; +Cc: Luiz Fernando Capitulino, lkml, netdev, robert.olsson
In-Reply-To: <20060129232342.1e481f9a@localhost>


Luiz Fernando Capitulino writes:

 > [PATCH 1/4]  pktgen: Lindent run.
 > [PATCH 2/4]  pktgen: Ports thread list to Kernel list implementation.
 > [PATCH 3/4]  pktgen: Fix kernel_thread() fail leak.
 > [PATCH 4/4]  pktgen: Fix Initialization fail leak.
 > 
 >  The changes from V1 are:
 > 
 >  1. More fixes made by hand after Lindent run
 >  2. Re-diffed agains't Dave's net-2.6.17 tree

 Should be fine I've used the previous version of the patches for a
 couple of days now. Thanks.

 Signed-off-by: Robert Olsson <robert.olsson@its.uu.se>

 Cheers.	
					--ro

^ permalink raw reply

* Re: [PATCH 0/4] - pktgen: refinements and small fixes (V2).
From: Luiz Fernando Capitulino @ 2006-01-30 12:15 UTC (permalink / raw)
  To: Robert Olsson; +Cc: davem, linux-kernel, netdev, robert.olsson
In-Reply-To: <17373.62964.203852.42375@robur.slu.se>

On Mon, 30 Jan 2006 12:18:12 +0100
Robert Olsson <Robert.Olsson@data.slu.se> wrote:

| 
| Luiz Fernando Capitulino writes:
| 
|  > [PATCH 1/4]  pktgen: Lindent run.
|  > [PATCH 2/4]  pktgen: Ports thread list to Kernel list implementation.
|  > [PATCH 3/4]  pktgen: Fix kernel_thread() fail leak.
|  > [PATCH 4/4]  pktgen: Fix Initialization fail leak.
|  > 
|  >  The changes from V1 are:
|  > 
|  >  1. More fixes made by hand after Lindent run
|  >  2. Re-diffed agains't Dave's net-2.6.17 tree
| 
|  Should be fine I've used the previous version of the patches for a
|  couple of days now. Thanks.

 Ok Robert, I'll try to finish the interface list port this week.

| 
|  Signed-off-by: Robert Olsson <robert.olsson@its.uu.se>
| 
|  Cheers.	
| 					--ro

-- 
Luiz Fernando N. Capitulino

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox