Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH 4/4] Initialize and fill IPv6 route age
From: Krishna Kumar2 @ 2007-07-23  7:56 UTC (permalink / raw)
  To: Varun Chandramohan; +Cc: dlstevens, netdev, sri, Varun Chandramohan
In-Reply-To: <20070723101318.c773f600.varunc@linux.vnet.ibm.com>

> +   if (dumpflg)
> +      NLA_PUT_U32(skb, RTA_AGE, timeval_to_sec(&tv) - rt->rt6i_age);
> +   else
> +      NLA_PUT_U32(skb, RTA_AGE, rt->rt6i_age);

Makes more sense (and easy to understand) if you use :

if (dumpflg == RT6_GET_ROUTE_INFO)
      ...
so that your code does not break if someone changed the #define values.

- KK

netdev-owner@vger.kernel.org wrote on 07/23/2007 10:13:18 AM:

> The age field of the ipv6 route structures are initilized with the
current
> timeval at the time of route       creation. When the route dump is
called the
> route age value stored in the structure is subtracted from the
present
> timeval and the difference is passed on as the route age.
>
> Signed-off-by: Varun Chandramohan <varunc@linux.vnet.ibm.com>
> ---
>  include/net/ip6_fib.h   |    1 +
>  include/net/ip6_route.h |    3 +++
>  net/ipv6/addrconf.c     |    5 +++++
>  net/ipv6/route.c        |   23 +++++++++++++++++++----
>  4 files changed, 28 insertions(+), 4 deletions(-)
>
> diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
> index c48ea87..e30a1cf 100644
> --- a/include/net/ip6_fib.h
> +++ b/include/net/ip6_fib.h
> @@ -98,6 +98,7 @@ struct rt6_info
>
>     u32            rt6i_flags;
>     u32            rt6i_metric;
> +   time_t            rt6i_age;
>     atomic_t         rt6i_ref;
>     struct fib6_table      *rt6i_table;
>
> diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
> index 5456fdd..fc9716c 100644
> --- a/include/net/ip6_route.h
> +++ b/include/net/ip6_route.h
> @@ -36,6 +36,9 @@ struct route_info {
>  #define RT6_LOOKUP_F_REACHABLE   0x2
>  #define RT6_LOOKUP_F_HAS_SADDR   0x4
>
> +#define RT6_SET_ROUTE_INFO 0x0
> +#define RT6_GET_ROUTE_INFO 0x1
> +
>  extern struct rt6_info   ip6_null_entry;
>
>  #ifdef CONFIG_IPV6_MULTIPLE_TABLES
> diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
> index 5a5f8bd..715c766 100644
> --- a/net/ipv6/addrconf.c
> +++ b/net/ipv6/addrconf.c
> @@ -4187,6 +4187,7 @@ EXPORT_SYMBOL(unregister_inet6addr_notif
>
>  int __init addrconf_init(void)
>  {
> +   struct timeval tv;
>     int err = 0;
>
>     /* The addrconf netdev notifier requires that loopback_dev
> @@ -4214,10 +4215,14 @@ int __init addrconf_init(void)
>     if (err)
>        return err;
>
> +   do_gettimeofday(&tv);
>     ip6_null_entry.rt6i_idev = in6_dev_get(&loopback_dev);
> +   ip6_null_entry.rt6i_age = timeval_to_sec(&tv);
>  #ifdef CONFIG_IPV6_MULTIPLE_TABLES
>     ip6_prohibit_entry.rt6i_idev = in6_dev_get(&loopback_dev);
> +   ip6_prohibit_entry.rt6i_age = timeval_to_sec(&tv);
>     ip6_blk_hole_entry.rt6i_idev = in6_dev_get(&loopback_dev);
> +   ip6_blk_hole_entry.rt6i_age = timeval_to_sec(&tv);
>  #endif
>
>     register_netdevice_notifier(&ipv6_dev_notf);
> diff --git a/net/ipv6/route.c b/net/ipv6/route.c
> index fe8d983..9386c05 100644
> --- a/net/ipv6/route.c
> +++ b/net/ipv6/route.c
> @@ -600,7 +600,14 @@ static int __ip6_ins_rt(struct rt6_info
>  {
>     int err;
>     struct fib6_table *table;
> +   struct timeval tv;
>
> +   do_gettimeofday(&tv);
> +   /* Update the timeval for new routes
> +    * We add it here to make it common irrespective
> +    * of how the new route is added.
> +    */
> +   rt->rt6i_age = timeval_to_sec(&tv);
>     table = rt->rt6i_table;
>     write_lock_bh(&table->tb6_lock);
>     err = fib6_add(&table->tb6_root, rt, info);
> @@ -2111,6 +2118,7 @@ static inline size_t rt6_nlmsg_size(void
>            + nla_total_size(4) /* RTA_IIF */
>            + nla_total_size(4) /* RTA_OIF */
>            + nla_total_size(4) /* RTA_PRIORITY */
> +          + nla_total_size(4) /*RTA_AGE*/
>            + RTAX_MAX * nla_total_size(4) /* RTA_METRICS */
>            + nla_total_size(sizeof(struct rta_cacheinfo));
>  }
> @@ -2118,10 +2126,11 @@ static inline size_t rt6_nlmsg_size(void
>  static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
>            struct in6_addr *dst, struct in6_addr *src,
>            int iif, int type, u32 pid, u32 seq,
> -          int prefix, unsigned int flags)
> +          int prefix, unsigned int flags, int dumpflg)
>  {
>     struct rtmsg *rtm;
>     struct nlmsghdr *nlh;
> +   struct timeval tv;
>     long expires;
>     u32 table;
>
> @@ -2185,6 +2194,12 @@ static int rt6_fill_node(struct sk_buff
>        if (ipv6_get_saddr(&rt->u.dst, dst, &saddr_buf) == 0)
>           NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf);
>     }
> +
> +   do_gettimeofday(&tv);
> +   if (dumpflg)
> +      NLA_PUT_U32(skb, RTA_AGE, timeval_to_sec(&tv) - rt->rt6i_age);
> +   else
> +      NLA_PUT_U32(skb, RTA_AGE, rt->rt6i_age);
>
>     if (rtnetlink_put_metrics(skb, rt->u.dst.metrics) < 0)
>        goto nla_put_failure;
> @@ -2222,7 +2237,7 @@ int rt6_dump_route(struct rt6_info *rt,
>
>     return rt6_fill_node(arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE,
>             NETLINK_CB(arg->cb->skb).pid, arg->cb->nlh->nlmsg_seq,
> -           prefix, NLM_F_MULTI);
> +           prefix, NLM_F_MULTI, RT6_GET_ROUTE_INFO);
>  }
>
>  static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr*
nlh, void *arg)
> @@ -2287,7 +2302,7 @@ static int inet6_rtm_getroute(struct sk_
>
>     err = rt6_fill_node(skb, rt, &fl.fl6_dst, &fl.fl6_src, iif,
>               RTM_NEWROUTE, NETLINK_CB(in_skb).pid,
> -             nlh->nlmsg_seq, 0, 0);
> +             nlh->nlmsg_seq, 0, 0, RT6_GET_ROUTE_INFO);
>     if (err < 0) {
>        kfree_skb(skb);
>        goto errout;
> @@ -2316,7 +2331,7 @@ void inet6_rt_notify(int event, struct r
>     if (skb == NULL)
>        goto errout;
>
> -   err = rt6_fill_node(skb, rt, NULL, NULL, 0, event, pid, seq, 0, 0);
> +   err = rt6_fill_node(skb, rt, NULL, NULL, 0, event, pid, seq, 0, 0,
> RT6_SET_ROUTE_INFO);
>     if (err < 0) {
>        /* -EMSGSIZE implies BUG in rt6_nlmsg_size() */
>        WARN_ON(err == -EMSGSIZE);
> --
> 1.4.3.4
>
> -
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


^ permalink raw reply

* Re: net/bluetooth/rfcomm/tty.c: use-after-free
From: Marcel Holtmann @ 2007-07-23  7:47 UTC (permalink / raw)
  To: Adrian Bunk; +Cc: Ville Tervo, netdev, bluez-devel, maxk, linux-kernel
In-Reply-To: <20070723012543.GW26212@stusta.de>

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

Hi Adrian,

> Commit 8de0a15483b357d0f0b821330ec84d1660cadc4e added the following 
> use-after-free in net/bluetooth/rfcomm/tty.c:
> 
> <--  snip  -->
> 
> ...
> static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
> {
> ...
>         if (IS_ERR(dev->tty_dev)) {
>                 list_del(&dev->list);
>                 kfree(dev);
>                 return PTR_ERR(dev->tty_dev);
>         }
> ...
> 
> <--  snip  -->
> 
> Spotted by the Coverity checker.

really good catch. I fully overlooked that one. The attached patch
should fix it.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>

Regards

Marcel


[-- Attachment #2: patch --]
[-- Type: text/x-patch, Size: 646 bytes --]

diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index 23ba61a..22a8320 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -267,7 +267,7 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
 out:
 	write_unlock_bh(&rfcomm_dev_lock);
 
-	if (err) {
+	if (err < 0) {
 		kfree(dev);
 		return err;
 	}
@@ -275,9 +275,10 @@ out:
 	dev->tty_dev = tty_register_device(rfcomm_tty_driver, dev->id, NULL);
 
 	if (IS_ERR(dev->tty_dev)) {
+		err = PTR_ERR(dev->tty_dev);
 		list_del(&dev->list);
 		kfree(dev);
-		return PTR_ERR(dev->tty_dev);
+		return err;
 	}
 
 	return dev->id;

[-- Attachment #3: Type: text/plain, Size: 315 bytes --]

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/

[-- Attachment #4: Type: text/plain, Size: 164 bytes --]

_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply related

* Re: [PATCH] [IrDA] KS959 USB IrDA dongle support
From: David Miller @ 2007-07-23  7:26 UTC (permalink / raw)
  To: samuel; +Cc: netdev, a_villacis, linux-usb-devel, irda-users
In-Reply-To: <kjg2gBqm.1185175506.5213420.samuel@sortiz.org>

From: "Samuel Ortiz" <samuel@sortiz.org>
Date: 23 Jul 2007 07:25:06 -0000

> I submitted it as soon as it was ready. Will we have to wait until the
> 2.6.24 merge window, or can it be applied earlier as it's a fully
> standalone driver ?

Please wait until I open up a net-2.6.24 tree, you can submit
it to me then.

Thanks.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

^ permalink raw reply

* Re: [PATCH] [IrDA] KS959 USB IrDA dongle support
From: Samuel Ortiz @ 2007-07-23  7:25 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	a_villacis-5itmuRygkZmgSpxsJD1C4w@public.gmane.org,
	linux-usb-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org,
	irda-users-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
In-Reply-To: <20070722.183506.121297628.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>


On 7/23/2007, "David Miller" <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org> wrote:

>From: Samuel Ortiz <samuel-jcdQHdrhKHMdnm+yROfE0A@public.gmane.org>
>Date: Mon, 23 Jul 2007 00:32:17 +0300
>
>> Last IrDA patch for 2.6.23-rc1, if it's not too late...
>
>Too late, Linus just closed the merge window, you had two
>weeks to submit this :-)
Too bad...
I submitted it as soon as it was ready. Will we have to wait until the
2.6.24 merge window, or can it be applied earlier as it's a fully
standalone driver ?

Cheers,
Samuel.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/

^ permalink raw reply

* Re: drivers/net/xen-netfront.c: bogus code
From: Jeremy Fitzhardinge @ 2007-07-23  6:46 UTC (permalink / raw)
  To: Adrian Bunk
  Cc: Jeremy Fitzhardinge, Chris Wright, Jeff Garzik, xen-devel, netdev,
	linux-kernel
In-Reply-To: <20070722232618.GO26212@stusta.de>

Adrian Bunk wrote:
> The Coverity checker spotted the following bogus code
> in drivers/net/xen-netfront.c:
>
> <--  snip  -->
>
> ...
> static void xennet_alloc_rx_buffers(struct net_device *dev)
> {
> ...
>         for (nr_flips = i = 0; ; i++) {
>                 skb = __skb_dequeue(&np->rx_batch);
>                 if (skb == NULL)
>                         break;
>
>                 skb->dev = dev;
>
>                 id = xennet_rxidx(req_prod + i);
>
>                 BUG_ON(np->rx_skbs[id]);
>                 np->rx_skbs[id] = skb;
>
>                 ref = gnttab_claim_grant_reference(&np->gref_rx_head);
>                 BUG_ON((signed short)ref < 0);
>                 np->grant_rx_ref[id] = ref;
>
>                 pfn = page_to_pfn(skb_shinfo(skb)->frags[0].page);
>                 vaddr = page_address(skb_shinfo(skb)->frags[0].page);
>
>                 req = RING_GET_REQUEST(&np->rx, req_prod + i);
>                 gnttab_grant_foreign_access_ref(ref,
>                                                 np->xbdev->otherend_id,
>                                                 pfn_to_mfn(pfn),
>                                                 0);
>
>                 req->id = id;
>                 req->gref = ref;
>         }
>
>         if (nr_flips != 0) {
> ...
>
> <--  snip  -->
>
> Note that "nr_flips" is always 0 in the last line.
>   

Thanks.  That's probably a residual from me removing the page-flipping
code.  I'll give it another pass.

    J

^ permalink raw reply

* [PATCH 2.6.22 4/4]S2IO: Implementing review comments from old patches
From: Veena Parat @ 2007-07-23  6:39 UTC (permalink / raw)
  To: netdev, jeff; +Cc: support

 - Incorporated Jeff Garzik's comments on coding standards

Signed-off-by: Veena Parat <veena.parat@neterion.com>
---
diff -urpN patch_3/drivers/net/s2io.c patch_4/drivers/net/s2io.c
--- patch_3/drivers/net/s2io.c	2007-07-19 17:44:54.000000000 +0530
+++ patch_4/drivers/net/s2io.c	2007-07-19 17:45:41.000000000 +0530
@@ -84,7 +84,7 @@
 #include "s2io.h"
 #include "s2io-regs.h"
 
-#define DRV_VERSION "2.0.23.1"
+#define DRV_VERSION "2.0.24.1"
 
 /* S2io Driver name & version. */
 static char s2io_driver_name[] = "Neterion";
@@ -4818,15 +4818,15 @@ static void s2io_ethtool_gringparam(stru
 		ering->rx_max_pending = MAX_RX_DESC_2;
 
 	ering->tx_max_pending = MAX_TX_DESC;
-	for (i = 0 ; i < sp->config.tx_fifo_num ; i++) {
+	for (i = 0 ; i < sp->config.tx_fifo_num ; i++) 
 		tx_desc_count += sp->config.tx_cfg[i].fifo_len;
-	}
+	
 	DBG_PRINT(INFO_DBG,"\nmax txds : %d\n",sp->config.max_txds);
 	ering->tx_pending = tx_desc_count;
 	rx_desc_count = 0;
-	for (i = 0 ; i < sp->config.rx_ring_num ; i++) {
+	for (i = 0 ; i < sp->config.rx_ring_num ; i++) 
 		rx_desc_count += sp->config.rx_cfg[i].num_rxd;
-	}
+
 	ering->rx_pending = rx_desc_count;
 
 	ering->rx_mini_max_pending = 0;


^ permalink raw reply

* [PATCH 2.6.22 3/4]S2IO: Checking for the return value of pci map function
From: Veena Parat @ 2007-07-23  6:37 UTC (permalink / raw)
  To: netdev, jeff; +Cc: support

 - Checking for the return value of pci map function
 - Implemented Francois Romieu's comments on eliminating code duplication
   using goto
 - Implemented Francois Romieu's comments on using a temporary variable for
   accessing statistics structure

Signed-off-by: Veena Parat <veena.parat@neterion.com>
---
diff -urpN patch_2/drivers/net/s2io.c patch_3/drivers/net/s2io.c
--- patch_2/drivers/net/s2io.c	2007-07-19 15:09:20.000000000 +0530
+++ patch_3/drivers/net/s2io.c	2007-07-19 17:44:54.000000000 +0530
@@ -282,6 +282,7 @@ static char ethtool_driver_stats_keys[][
 	("lro_flush_due_to_max_pkts"),
 	("lro_avg_aggr_pkts"),
 	("mem_alloc_fail_cnt"),
+	("pci_map_fail_cnt"),
 	("watchdog_timer_cnt"),
 	("mem_allocated"),
 	("mem_freed"),
@@ -2271,6 +2272,7 @@ static int fill_rx_buffers(struct s2io_n
 	u64 Buffer0_ptr = 0, Buffer1_ptr = 0;
 	struct RxD1 *rxdp1;
 	struct RxD3 *rxdp3;
+	struct swStat *stats = &nic->mac_control.stats_info->sw_stat;
 
 	mac_control = &nic->mac_control;
 	config = &nic->config;
@@ -2360,6 +2362,11 @@ static int fill_rx_buffers(struct s2io_n
 			rxdp1->Buffer0_ptr = pci_map_single
 			    (nic->pdev, skb->data, size - NET_IP_ALIGN,
 				PCI_DMA_FROMDEVICE);
+			if( (rxdp1->Buffer0_ptr == 0) ||
+				(rxdp1->Buffer0_ptr ==
+				DMA_ERROR_CODE))
+				goto pci_map_failed;
+
 			rxdp->Control_2 = 
 				SET_BUFFER0_SIZE_1(size - NET_IP_ALIGN);
 
@@ -2395,6 +2402,10 @@ static int fill_rx_buffers(struct s2io_n
 				pci_dma_sync_single_for_device(nic->pdev,
 				(dma_addr_t) rxdp3->Buffer0_ptr,
 				    BUF0_LEN, PCI_DMA_FROMDEVICE);
+			if( (rxdp3->Buffer0_ptr == 0) ||
+				(rxdp3->Buffer0_ptr == DMA_ERROR_CODE))
+				goto pci_map_failed;
+
 			rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN);
 			if (nic->rxd_mode == RXD_MODE_3B) {
 				/* Two buffer mode */
@@ -2407,12 +2418,22 @@ static int fill_rx_buffers(struct s2io_n
 				(nic->pdev, skb->data, dev->mtu + 4,
 						PCI_DMA_FROMDEVICE);
 
-				/* Buffer-1 will be dummy buffer. Not used */
-				if (!(rxdp3->Buffer1_ptr)) {
-					rxdp3->Buffer1_ptr =
+				if( (rxdp3->Buffer2_ptr == 0) ||
+					(rxdp3->Buffer2_ptr == DMA_ERROR_CODE))
+					goto pci_map_failed;
+
+				rxdp3->Buffer1_ptr =
 						pci_map_single(nic->pdev,
 						ba->ba_1, BUF1_LEN,
 						PCI_DMA_FROMDEVICE);
+				if( (rxdp3->Buffer1_ptr == 0) ||
+					(rxdp3->Buffer1_ptr == DMA_ERROR_CODE)) {
+					pci_unmap_single
+						(nic->pdev,
+						(dma_addr_t)skb->data,
+						dev->mtu + 4,
+						PCI_DMA_FROMDEVICE);
+					goto pci_map_failed;
 				}
 				rxdp->Control_2 |= SET_BUFFER1_SIZE_3(1);
 				rxdp->Control_2 |= SET_BUFFER2_SIZE_3
@@ -2451,6 +2472,11 @@ static int fill_rx_buffers(struct s2io_n
 	}
 
 	return SUCCESS;
+pci_map_failed:
+	stats->pci_map_fail_cnt++;
+	stats->mem_freed += skb->truesize;
+	dev_kfree_skb_irq(skb);
+	return -ENOMEM;
 }
 
 static void free_rxd_blk(struct s2io_nic *sp, int ring_no, int blk)
@@ -3882,6 +3908,7 @@ static int s2io_xmit(struct sk_buff *skb
 	struct mac_info *mac_control;
 	struct config_param *config;
 	int offload_type;
+	struct swStat *stats = &sp->mac_control.stats_info->sw_stat;
 
 	mac_control = &sp->mac_control;
 	config = &sp->config;
@@ -3966,11 +3993,18 @@ static int s2io_xmit(struct sk_buff *skb
 		txdp->Buffer_Pointer = pci_map_single(sp->pdev,
 					sp->ufo_in_band_v,
 					sizeof(u64), PCI_DMA_TODEVICE);
+		if((txdp->Buffer_Pointer == 0) ||
+			(txdp->Buffer_Pointer == DMA_ERROR_CODE))
+			goto pci_map_failed;
 		txdp++;
 	}
 
 	txdp->Buffer_Pointer = pci_map_single
 	    (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE);
+	if((txdp->Buffer_Pointer == 0) ||
+		(txdp->Buffer_Pointer == DMA_ERROR_CODE))
+		goto pci_map_failed;
+
 	txdp->Host_Control = (unsigned long) skb;
 	txdp->Control_1 |= TXD_BUFFER0_SIZE(frg_len);
 	if (offload_type == SKB_GSO_UDP)
@@ -4027,6 +4061,13 @@ static int s2io_xmit(struct sk_buff *skb
 	spin_unlock_irqrestore(&sp->tx_lock, flags);
 
 	return 0;
+pci_map_failed:
+	stats->pci_map_fail_cnt++;
+	netif_stop_queue(dev);
+	stats->mem_freed += skb->truesize;
+	dev_kfree_skb(skb);
+	spin_unlock_irqrestore(&sp->tx_lock, flags);
+	return 0;
 }
 
 static void
@@ -5769,6 +5810,7 @@ static void s2io_get_ethtool_stats(struc
 	else
 		tmp_stats[i++] = 0;
 	tmp_stats[i++] = stat_info->sw_stat.mem_alloc_fail_cnt;
+	tmp_stats[i++] = stat_info->sw_stat.pci_map_fail_cnt;
 	tmp_stats[i++] = stat_info->sw_stat.watchdog_timer_cnt;
 	tmp_stats[i++] = stat_info->sw_stat.mem_allocated;
 	tmp_stats[i++] = stat_info->sw_stat.mem_freed;
@@ -6112,6 +6154,7 @@ static int set_rxd_buffer_pointer(struct
 				u64 *temp2, int size)
 {
 	struct net_device *dev = sp->dev;
+	struct swStat *stats = &sp->mac_control.stats_info->sw_stat;
 
 	if ((sp->rxd_mode == RXD_MODE_1) && (rxdp->Host_Control == 0)) {
 		struct RxD1 *rxdp1 = (struct RxD1 *)rxdp;
@@ -6144,6 +6187,10 @@ static int set_rxd_buffer_pointer(struct
 				pci_map_single( sp->pdev, (*skb)->data,
 					size - NET_IP_ALIGN,
 					PCI_DMA_FROMDEVICE);
+			if( (rxdp1->Buffer0_ptr == 0) ||
+				(rxdp1->Buffer0_ptr == DMA_ERROR_CODE)) {
+				goto memalloc_failed;
+			}
 			rxdp->Host_Control = (unsigned long) (*skb);
 		}
 	} else if ((sp->rxd_mode == RXD_MODE_3B) && (rxdp->Host_Control == 0)) {
@@ -6169,19 +6216,43 @@ static int set_rxd_buffer_pointer(struct
 				pci_map_single(sp->pdev, (*skb)->data,
 					       dev->mtu + 4,
 					       PCI_DMA_FROMDEVICE);
+			if( (rxdp3->Buffer2_ptr == 0) ||
+				(rxdp3->Buffer2_ptr == DMA_ERROR_CODE)) {
+				goto memalloc_failed;
+			}
 			rxdp3->Buffer0_ptr = *temp0 =
 				pci_map_single( sp->pdev, ba->ba_0, BUF0_LEN,
 						PCI_DMA_FROMDEVICE);
+			if( (rxdp3->Buffer0_ptr == 0) ||
+				(rxdp3->Buffer0_ptr == DMA_ERROR_CODE)) {
+				pci_unmap_single (sp->pdev,
+					(dma_addr_t)(*skb)->data,
+					dev->mtu + 4, PCI_DMA_FROMDEVICE);
+				goto memalloc_failed;
+			}
 			rxdp->Host_Control = (unsigned long) (*skb);
 
 			/* Buffer-1 will be dummy buffer not used */
 			rxdp3->Buffer1_ptr = *temp1 =
 				pci_map_single(sp->pdev, ba->ba_1, BUF1_LEN,
 						PCI_DMA_FROMDEVICE);
+			if( (rxdp3->Buffer1_ptr == 0) ||
+				(rxdp3->Buffer1_ptr == DMA_ERROR_CODE)) {
+				pci_unmap_single (sp->pdev,
+					(dma_addr_t)(*skb)->data,
+					dev->mtu + 4, PCI_DMA_FROMDEVICE);
+				goto memalloc_failed;
+			}
 		}
 	}
 	return 0;
+	memalloc_failed:
+		stats->pci_map_fail_cnt++;
+		stats->mem_freed += (*skb)->truesize;
+		dev_kfree_skb(*skb);
+		return -ENOMEM;
 }
+
 static void set_rxd_buffer_size(struct s2io_nic *sp, struct RxD_t *rxdp,
 				int size)
 {
diff -urpN patch_2/drivers/net/s2io.h patch_3/drivers/net/s2io.h
--- patch_2/drivers/net/s2io.h	2007-07-19 15:09:20.000000000 +0530
+++ patch_3/drivers/net/s2io.h	2007-07-19 16:45:26.000000000 +0530
@@ -74,6 +74,10 @@ static int debug_level = ERR_DBG;
 /* DEBUG message print. */
 #define DBG_PRINT(dbg_level, args...)  if(!(debug_level<dbg_level)) printk(args)
 
+#ifndef DMA_ERROR_CODE
+#define DMA_ERROR_CODE          (~(dma_addr_t)0x0)
+#endif
+
 /* Protocol assist features of the NIC */
 #define L3_CKSUM_OK 0xFFFF
 #define L4_CKSUM_OK 0xFFFF
@@ -97,6 +101,7 @@ struct swStat {
 	unsigned long long num_aggregations;
 	/* Other statistics */
 	unsigned long long mem_alloc_fail_cnt;
+	unsigned long long pci_map_fail_cnt;
 	unsigned long long watchdog_timer_cnt;
 	unsigned long long mem_allocated;
 	unsigned long long mem_freed;


^ permalink raw reply

* RE: [PATCH 2.6.22 1/4]S2IO: Removing MSI support from driver
From: Veena Parat @ 2007-07-23  6:33 UTC (permalink / raw)
  To: Veena Parat, netdev, jeff; +Cc: support
In-Reply-To: <Pine.GSO.4.10.10707230221490.2793-100000@guinness>

Hi,

The patch number is incorrect in the below mail. It should be 
[PATCH 2.6.22 2/4] instead of [PATCH 2.6.22 1/4].
Pls consider it as the second patch in this series.
Sorry for the inconvenience.

Regards
Veena

-----Original Message-----
From: Veena Parat [mailto:Veena.Parat@neterion.com] 
Sent: Monday, July 23, 2007 11:54 AM
To: netdev@vger.kernel.org; jeff@garzik.org
Cc: support
Subject: [PATCH 2.6.22 1/4]S2IO: Removing MSI support from driver

 - Removed MSI support from driver - unused feature
 - Replaced request_mem_region with pci_request_regions
 
Signed-off-by: Veena Parat <veena.parat@neterion.com>
---
diff -urpN patch_1/drivers/net/s2io.c patch_2/drivers/net/s2io.c
--- patch_1/drivers/net/s2io.c	2007-07-19 14:20:53.000000000 +0530
+++ patch_2/drivers/net/s2io.c	2007-07-19 15:08:18.000000000 +0530
@@ -37,7 +37,7 @@
  * tx_fifo_len: This too is an array of 8. Each element defines the
number of
  * Tx descriptors that can be associated with each corresponding FIFO.
  * intr_type: This defines the type of interrupt. The values can be
0(INTA),
- *     1(MSI), 2(MSI_X). Default value is '0(INTA)'
+ *     2(MSI_X). Default value is '0(INTA)'
  * lro: Specifies whether to enable Large Receive Offload (LRO) or not.
  *     Possible values '1' for enable '0' for disable. Default is '0'
  * lro_max_pkts: This parameter defines maximum number of packets can
be
@@ -426,7 +426,7 @@ S2IO_PARM_INT(bimodal, 0);
 S2IO_PARM_INT(l3l4hdr_size, 128);
 /* Frequency of Rx desc syncs expressed as power of 2 */
 S2IO_PARM_INT(rxsync_frequency, 3);
-/* Interrupt type. Values can be 0(INTA), 1(MSI), 2(MSI_X) */
+/* Interrupt type. Values can be 0(INTA), 2(MSI_X) */
 S2IO_PARM_INT(intr_type, 0);
 /* Large receive offload feature */
 S2IO_PARM_INT(lro, 0);
@@ -3662,56 +3662,6 @@ static void store_xmsi_data(struct s2io_
 	}
 }
 
-int s2io_enable_msi(struct s2io_nic *nic)
-{
-	struct XENA_dev_config __iomem *bar0 = nic->bar0;
-	u16 msi_ctrl, msg_val;
-	struct config_param *config = &nic->config;
-	struct net_device *dev = nic->dev;
-	u64 val64, tx_mat, rx_mat;
-	int i, err;
-
-	val64 = readq(&bar0->pic_control);
-	val64 &= ~BIT(1);
-	writeq(val64, &bar0->pic_control);
-
-	err = pci_enable_msi(nic->pdev);
-	if (err) {
-		DBG_PRINT(ERR_DBG, "%s: enabling MSI failed\n",
-			  nic->dev->name);
-		return err;
-	}
-
-	/*
-	 * Enable MSI and use MSI-1 in stead of the standard MSI-0
-	 * for interrupt handling.
-	 */
-	pci_read_config_word(nic->pdev, 0x4c, &msg_val);
-	msg_val ^= 0x1;
-	pci_write_config_word(nic->pdev, 0x4c, msg_val);
-	pci_read_config_word(nic->pdev, 0x4c, &msg_val);
-
-	pci_read_config_word(nic->pdev, 0x42, &msi_ctrl);
-	msi_ctrl |= 0x10;
-	pci_write_config_word(nic->pdev, 0x42, msi_ctrl);
-
-	/* program MSI-1 into all usable Tx_Mat and Rx_Mat fields */
-	tx_mat = readq(&bar0->tx_mat0_n[0]);
-	for (i=0; i<config->tx_fifo_num; i++) {
-		tx_mat |= TX_MAT_SET(i, 1);
-	}
-	writeq(tx_mat, &bar0->tx_mat0_n[0]);
-
-	rx_mat = readq(&bar0->rx_mat);
-	for (i=0; i<config->rx_ring_num; i++) {
-		rx_mat |= RX_MAT_SET(i, 1);
-	}
-	writeq(rx_mat, &bar0->rx_mat);
-
-	dev->irq = nic->pdev->irq;
-	return 0;
-}
-
 static int s2io_enable_msi_x(struct s2io_nic *nic)
 {
 	struct XENA_dev_config __iomem *bar0 = nic->bar0;
@@ -4117,39 +4067,6 @@ static int s2io_chk_rx_buffers(struct s2
 	return 0;
 }
 
-static irqreturn_t s2io_msi_handle(int irq, void *dev_id)
-{
-	struct net_device *dev = (struct net_device *) dev_id;
-	struct s2io_nic *sp = dev->priv;
-	int i;
-	struct mac_info *mac_control;
-	struct config_param *config;
-
-	atomic_inc(&sp->isr_cnt);
-	mac_control = &sp->mac_control;
-	config = &sp->config;
-	DBG_PRINT(INTR_DBG, "%s: MSI handler\n", __FUNCTION__);
-
-	/* If Intr is because of Rx Traffic */
-	for (i = 0; i < config->rx_ring_num; i++)
-		rx_intr_handler(&mac_control->rings[i]);
-
-	/* If Intr is because of Tx Traffic */
-	for (i = 0; i < config->tx_fifo_num; i++)
-		tx_intr_handler(&mac_control->fifos[i]);
-
-	/*
-	 * If the Rx buffer count is below the panic threshold then
-	 * reallocate the buffers from the interrupt handler itself,
-	 * else schedule a tasklet to reallocate the buffers.
-	 */
-	for (i = 0; i < config->rx_ring_num; i++)
-		s2io_chk_rx_buffers(sp, i);
-
-	atomic_dec(&sp->isr_cnt);
-	return IRQ_HANDLED;
-}
-
 static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id)
 {
 	struct ring_info *ring = (struct ring_info *)dev_id;
@@ -6332,9 +6249,7 @@ static int s2io_add_isr(struct s2io_nic 
 	struct net_device *dev = sp->dev;
 	int err = 0;
 
-	if (sp->intr_type == MSI)
-		ret = s2io_enable_msi(sp);
-	else if (sp->intr_type == MSI_X)
+	if (sp->intr_type == MSI_X)
 		ret = s2io_enable_msi_x(sp);
 	if (ret) {
 		DBG_PRINT(ERR_DBG, "%s: Defaulting to INTA\n",
dev->name);
@@ -6345,16 +6260,6 @@ static int s2io_add_isr(struct s2io_nic 
 	store_xmsi_data(sp);
 
 	/* After proper initialization of H/W, register ISR */
-	if (sp->intr_type == MSI) {
-		err = request_irq((int) sp->pdev->irq, s2io_msi_handle,
-			IRQF_SHARED, sp->name, dev);
-		if (err) {
-			pci_disable_msi(sp->pdev);
-			DBG_PRINT(ERR_DBG, "%s: MSI registration
failed\n",
-				  dev->name);
-			return -1;
-		}
-	}
 	if (sp->intr_type == MSI_X) {
 		int i, msix_tx_cnt=0,msix_rx_cnt=0;
 
@@ -6441,14 +6346,6 @@ static void s2io_rem_isr(struct s2io_nic
 		pci_disable_msix(sp->pdev);
 	} else {
 		free_irq(sp->pdev->irq, dev);
-		if (sp->intr_type == MSI) {
-			u16 val;
-
-			pci_disable_msi(sp->pdev);
-			pci_read_config_word(sp->pdev, 0x4c, &val);
-			val ^= 0x1;
-			pci_write_config_word(sp->pdev, 0x4c, val);
-		}
 	}
 	/* Waiting till all Interrupt handlers are complete */
 	cnt = 0;
@@ -6994,7 +6891,7 @@ static int s2io_verify_parm(struct pci_d
 		*dev_intr_type = INTA;
 	}
 #else
-	if (*dev_intr_type > MSI_X) {
+	if ((*dev_intr_type != INTA) && (*dev_intr_type != MSI_X)) {
 		DBG_PRINT(ERR_DBG, "s2io: Wrong intr_type requested. "
 			  "Defaulting to INTA\n");
 		*dev_intr_type = INTA;
@@ -7103,28 +7000,10 @@ s2io_init_nic(struct pci_dev *pdev, cons
 		pci_disable_device(pdev);
 		return -ENOMEM;
 	}
-	if (dev_intr_type != MSI_X) {
-		if (pci_request_regions(pdev, s2io_driver_name)) {
-			DBG_PRINT(ERR_DBG, "Request Regions failed\n");
-			pci_disable_device(pdev);
-			return -ENODEV;
-		}
-	}
-	else {
-		if (!(request_mem_region(pci_resource_start(pdev, 0),
-               	         pci_resource_len(pdev, 0),
s2io_driver_name))) {
-			DBG_PRINT(ERR_DBG, "bar0 Request Regions
failed\n");
-			pci_disable_device(pdev);
-			return -ENODEV;
-		}
-        	if (!(request_mem_region(pci_resource_start(pdev, 2),
-               	         pci_resource_len(pdev, 2),
s2io_driver_name))) {
-			DBG_PRINT(ERR_DBG, "bar1 Request Regions
failed\n");
-                	release_mem_region(pci_resource_start(pdev, 0),
-                                   pci_resource_len(pdev, 0));
-			pci_disable_device(pdev);
-			return -ENODEV;
-		}
+	if ((ret = pci_request_regions(pdev, s2io_driver_name))) {
+		DBG_PRINT(ERR_DBG, "%s: Request Regions failed - %x \n",
__FUNCTION__, ret);
+		pci_disable_device(pdev);
+		return -ENODEV;
 	}
 
 	dev = alloc_etherdev(sizeof(struct s2io_nic));
@@ -7434,9 +7313,6 @@ s2io_init_nic(struct pci_dev *pdev, cons
 		case INTA:
 		    DBG_PRINT(ERR_DBG, "%s: Interrupt type INTA\n",
dev->name);
 		    break;
-		case MSI:
-		    DBG_PRINT(ERR_DBG, "%s: Interrupt type MSI\n",
dev->name);
-		    break;
 		case MSI_X:
 		    DBG_PRINT(ERR_DBG, "%s: Interrupt type MSI-X\n",
dev->name);
 		    break;
@@ -7476,14 +7352,7 @@ s2io_init_nic(struct pci_dev *pdev, cons
       mem_alloc_failed:
 	free_shared_mem(sp);
 	pci_disable_device(pdev);
-	if (dev_intr_type != MSI_X)
-		pci_release_regions(pdev);
-	else {
-		release_mem_region(pci_resource_start(pdev, 0),
-			pci_resource_len(pdev, 0));
-		release_mem_region(pci_resource_start(pdev, 2),
-			pci_resource_len(pdev, 2));
-	}
+	pci_release_regions(pdev);
 	pci_set_drvdata(pdev, NULL);
 	free_netdev(dev);
 
@@ -7518,14 +7387,7 @@ static void __devexit s2io_rem_nic(struc
 	free_shared_mem(sp);
 	iounmap(sp->bar0);
 	iounmap(sp->bar1);
-	if (sp->intr_type != MSI_X)
-		pci_release_regions(pdev);
-	else {
-		release_mem_region(pci_resource_start(pdev, 0),
-			pci_resource_len(pdev, 0));
-		release_mem_region(pci_resource_start(pdev, 2),
-			pci_resource_len(pdev, 2));
-	}
+	pci_release_regions(pdev);
 	pci_set_drvdata(pdev, NULL);
 	free_netdev(dev);
 	pci_disable_device(pdev);
diff -urpN patch_1/drivers/net/s2io.h patch_2/drivers/net/s2io.h
--- patch_1/drivers/net/s2io.h	2007-07-19 14:20:53.000000000 +0530
+++ patch_2/drivers/net/s2io.h	2007-07-19 14:43:39.000000000 +0530
@@ -875,7 +875,6 @@ struct s2io_nic {
 	u16		lro_max_aggr_per_sess;
 
 #define INTA	0
-#define MSI	1
 #define MSI_X	2
 	u8 intr_type;
 
@@ -1019,8 +1018,6 @@ static int s2io_poll(struct net_device *
 static void s2io_init_pci(struct s2io_nic * sp);
 static int s2io_set_mac_addr(struct net_device *dev, u8 * addr);
 static void s2io_alarm_handle(unsigned long data);
-static int s2io_enable_msi(struct s2io_nic *nic);
-static irqreturn_t s2io_msi_handle(int irq, void *dev_id);
 static irqreturn_t
 s2io_msix_ring_handle(int irq, void *dev_id);
 static irqreturn_t


^ permalink raw reply

* [ofa-general] Re: [PATCH 02/10] Networking include file changes.
From: Krishna Kumar2 @ 2007-07-23  6:27 UTC (permalink / raw)
  To: Sridhar Samudrala
  Cc: jagana, johnpol, herbert, gaagaan, Robert.Olsson, kumarkr,
	mcarlson, peter.p.waskiewicz.jr, hadi, kaber, jeff, general,
	mchan, tgraf, netdev, davem, rdreier
In-Reply-To: <46A443CB.6060200@us.ibm.com>

Hi Sridhar,

Sridhar Samudrala <sri@us.ibm.com> wrote on 07/23/2007 11:29:39 AM:

> Krishna Kumar2 wrote:
> > Hi Sridhar,
> >
> > Sridhar Samudrala <sri@us.ibm.com> wrote on 07/20/2007 10:55:05 PM:
> >>> diff -ruNp org/include/net/pkt_sched.h new/include/net/pkt_sched.h
> >>> --- org/include/net/pkt_sched.h   2007-07-20 07:49:28.000000000 +0530
> >>> +++ new/include/net/pkt_sched.h   2007-07-20 08:30:22.000000000 +0530
> >>> @@ -80,13 +80,13 @@ extern struct qdisc_rate_table *qdisc_ge
> >>>        struct rtattr *tab);
> >>>  extern void qdisc_put_rtab(struct qdisc_rate_table *tab);
> >>>
> >>> -extern void __qdisc_run(struct net_device *dev);
> >>> +extern void __qdisc_run(struct net_device *dev, struct sk_buff_head
> > *blist);
> >> Why do we need this additional 'blist' argument?
> >> Is this different from dev->skb_blist?
> >
> > It is the same, but I want to call it mostly with NULL and rarely with
the
> > batch list pointer (so it is related to your other question). My
original
> > code didn't have this and was trying batching in all cases. But in most
> > xmit's (probably almost all), there will be only one packet in the
queue to
> > send and batching will never happen. When there is a lock contention or
if
> > the queue is stopped, then the next iteration will find >1 packets. But
I
> > still will try no batching for the lock failure case as there be
probably
> > 2 packets (one from previous time and 1 from this time, or 3 if two
> > failures,
> > etc), and try batching only when queue was stopped from net_tx_action
(this
> > was based on Dave Miller's idea).
>
> Is this right to say that the above change is to get this behavior?
>    If qdisc_run() is called from dev_queue_xmit() don't use batching.
>    If qdisc_run() is called from net_tx_action(), do batching.

Correct.

> Isn't it possible to have multiple skb's in the qdisc queue in the
> first case?

It is possible but rarer (so unnecessary checking most of the time). From
net_tx_action you are guaranteed to have multiple skbs, but from xmit you
will almost always get one skb (since most send of 1 skb will go out OK).
And also in the xmit path, it is more likely to have few skbs compared to
possibly hundreds in the net_tx_action path.

> If this additional argument is used to indicate if we should do batching
> or not, then passing a flag may be much more cleaner than passing the
blist.

OK, I will add this as another action item to check (along with Patrick's
suggestion to use single API) and will get back.

- KK

^ permalink raw reply

* [PATCH 2.6.22 1/4]S2IO: Removing MSI support from driver
From: Veena Parat @ 2007-07-23  6:23 UTC (permalink / raw)
  To: netdev, jeff; +Cc: support

 - Removed MSI support from driver - unused feature
 - Replaced request_mem_region with pci_request_regions
 
Signed-off-by: Veena Parat <veena.parat@neterion.com>
---
diff -urpN patch_1/drivers/net/s2io.c patch_2/drivers/net/s2io.c
--- patch_1/drivers/net/s2io.c	2007-07-19 14:20:53.000000000 +0530
+++ patch_2/drivers/net/s2io.c	2007-07-19 15:08:18.000000000 +0530
@@ -37,7 +37,7 @@
  * tx_fifo_len: This too is an array of 8. Each element defines the number of
  * Tx descriptors that can be associated with each corresponding FIFO.
  * intr_type: This defines the type of interrupt. The values can be 0(INTA),
- *     1(MSI), 2(MSI_X). Default value is '0(INTA)'
+ *     2(MSI_X). Default value is '0(INTA)'
  * lro: Specifies whether to enable Large Receive Offload (LRO) or not.
  *     Possible values '1' for enable '0' for disable. Default is '0'
  * lro_max_pkts: This parameter defines maximum number of packets can be
@@ -426,7 +426,7 @@ S2IO_PARM_INT(bimodal, 0);
 S2IO_PARM_INT(l3l4hdr_size, 128);
 /* Frequency of Rx desc syncs expressed as power of 2 */
 S2IO_PARM_INT(rxsync_frequency, 3);
-/* Interrupt type. Values can be 0(INTA), 1(MSI), 2(MSI_X) */
+/* Interrupt type. Values can be 0(INTA), 2(MSI_X) */
 S2IO_PARM_INT(intr_type, 0);
 /* Large receive offload feature */
 S2IO_PARM_INT(lro, 0);
@@ -3662,56 +3662,6 @@ static void store_xmsi_data(struct s2io_
 	}
 }
 
-int s2io_enable_msi(struct s2io_nic *nic)
-{
-	struct XENA_dev_config __iomem *bar0 = nic->bar0;
-	u16 msi_ctrl, msg_val;
-	struct config_param *config = &nic->config;
-	struct net_device *dev = nic->dev;
-	u64 val64, tx_mat, rx_mat;
-	int i, err;
-
-	val64 = readq(&bar0->pic_control);
-	val64 &= ~BIT(1);
-	writeq(val64, &bar0->pic_control);
-
-	err = pci_enable_msi(nic->pdev);
-	if (err) {
-		DBG_PRINT(ERR_DBG, "%s: enabling MSI failed\n",
-			  nic->dev->name);
-		return err;
-	}
-
-	/*
-	 * Enable MSI and use MSI-1 in stead of the standard MSI-0
-	 * for interrupt handling.
-	 */
-	pci_read_config_word(nic->pdev, 0x4c, &msg_val);
-	msg_val ^= 0x1;
-	pci_write_config_word(nic->pdev, 0x4c, msg_val);
-	pci_read_config_word(nic->pdev, 0x4c, &msg_val);
-
-	pci_read_config_word(nic->pdev, 0x42, &msi_ctrl);
-	msi_ctrl |= 0x10;
-	pci_write_config_word(nic->pdev, 0x42, msi_ctrl);
-
-	/* program MSI-1 into all usable Tx_Mat and Rx_Mat fields */
-	tx_mat = readq(&bar0->tx_mat0_n[0]);
-	for (i=0; i<config->tx_fifo_num; i++) {
-		tx_mat |= TX_MAT_SET(i, 1);
-	}
-	writeq(tx_mat, &bar0->tx_mat0_n[0]);
-
-	rx_mat = readq(&bar0->rx_mat);
-	for (i=0; i<config->rx_ring_num; i++) {
-		rx_mat |= RX_MAT_SET(i, 1);
-	}
-	writeq(rx_mat, &bar0->rx_mat);
-
-	dev->irq = nic->pdev->irq;
-	return 0;
-}
-
 static int s2io_enable_msi_x(struct s2io_nic *nic)
 {
 	struct XENA_dev_config __iomem *bar0 = nic->bar0;
@@ -4117,39 +4067,6 @@ static int s2io_chk_rx_buffers(struct s2
 	return 0;
 }
 
-static irqreturn_t s2io_msi_handle(int irq, void *dev_id)
-{
-	struct net_device *dev = (struct net_device *) dev_id;
-	struct s2io_nic *sp = dev->priv;
-	int i;
-	struct mac_info *mac_control;
-	struct config_param *config;
-
-	atomic_inc(&sp->isr_cnt);
-	mac_control = &sp->mac_control;
-	config = &sp->config;
-	DBG_PRINT(INTR_DBG, "%s: MSI handler\n", __FUNCTION__);
-
-	/* If Intr is because of Rx Traffic */
-	for (i = 0; i < config->rx_ring_num; i++)
-		rx_intr_handler(&mac_control->rings[i]);
-
-	/* If Intr is because of Tx Traffic */
-	for (i = 0; i < config->tx_fifo_num; i++)
-		tx_intr_handler(&mac_control->fifos[i]);
-
-	/*
-	 * If the Rx buffer count is below the panic threshold then
-	 * reallocate the buffers from the interrupt handler itself,
-	 * else schedule a tasklet to reallocate the buffers.
-	 */
-	for (i = 0; i < config->rx_ring_num; i++)
-		s2io_chk_rx_buffers(sp, i);
-
-	atomic_dec(&sp->isr_cnt);
-	return IRQ_HANDLED;
-}
-
 static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id)
 {
 	struct ring_info *ring = (struct ring_info *)dev_id;
@@ -6332,9 +6249,7 @@ static int s2io_add_isr(struct s2io_nic 
 	struct net_device *dev = sp->dev;
 	int err = 0;
 
-	if (sp->intr_type == MSI)
-		ret = s2io_enable_msi(sp);
-	else if (sp->intr_type == MSI_X)
+	if (sp->intr_type == MSI_X)
 		ret = s2io_enable_msi_x(sp);
 	if (ret) {
 		DBG_PRINT(ERR_DBG, "%s: Defaulting to INTA\n", dev->name);
@@ -6345,16 +6260,6 @@ static int s2io_add_isr(struct s2io_nic 
 	store_xmsi_data(sp);
 
 	/* After proper initialization of H/W, register ISR */
-	if (sp->intr_type == MSI) {
-		err = request_irq((int) sp->pdev->irq, s2io_msi_handle,
-			IRQF_SHARED, sp->name, dev);
-		if (err) {
-			pci_disable_msi(sp->pdev);
-			DBG_PRINT(ERR_DBG, "%s: MSI registration failed\n",
-				  dev->name);
-			return -1;
-		}
-	}
 	if (sp->intr_type == MSI_X) {
 		int i, msix_tx_cnt=0,msix_rx_cnt=0;
 
@@ -6441,14 +6346,6 @@ static void s2io_rem_isr(struct s2io_nic
 		pci_disable_msix(sp->pdev);
 	} else {
 		free_irq(sp->pdev->irq, dev);
-		if (sp->intr_type == MSI) {
-			u16 val;
-
-			pci_disable_msi(sp->pdev);
-			pci_read_config_word(sp->pdev, 0x4c, &val);
-			val ^= 0x1;
-			pci_write_config_word(sp->pdev, 0x4c, val);
-		}
 	}
 	/* Waiting till all Interrupt handlers are complete */
 	cnt = 0;
@@ -6994,7 +6891,7 @@ static int s2io_verify_parm(struct pci_d
 		*dev_intr_type = INTA;
 	}
 #else
-	if (*dev_intr_type > MSI_X) {
+	if ((*dev_intr_type != INTA) && (*dev_intr_type != MSI_X)) {
 		DBG_PRINT(ERR_DBG, "s2io: Wrong intr_type requested. "
 			  "Defaulting to INTA\n");
 		*dev_intr_type = INTA;
@@ -7103,28 +7000,10 @@ s2io_init_nic(struct pci_dev *pdev, cons
 		pci_disable_device(pdev);
 		return -ENOMEM;
 	}
-	if (dev_intr_type != MSI_X) {
-		if (pci_request_regions(pdev, s2io_driver_name)) {
-			DBG_PRINT(ERR_DBG, "Request Regions failed\n");
-			pci_disable_device(pdev);
-			return -ENODEV;
-		}
-	}
-	else {
-		if (!(request_mem_region(pci_resource_start(pdev, 0),
-               	         pci_resource_len(pdev, 0), s2io_driver_name))) {
-			DBG_PRINT(ERR_DBG, "bar0 Request Regions failed\n");
-			pci_disable_device(pdev);
-			return -ENODEV;
-		}
-        	if (!(request_mem_region(pci_resource_start(pdev, 2),
-               	         pci_resource_len(pdev, 2), s2io_driver_name))) {
-			DBG_PRINT(ERR_DBG, "bar1 Request Regions failed\n");
-                	release_mem_region(pci_resource_start(pdev, 0),
-                                   pci_resource_len(pdev, 0));
-			pci_disable_device(pdev);
-			return -ENODEV;
-		}
+	if ((ret = pci_request_regions(pdev, s2io_driver_name))) {
+		DBG_PRINT(ERR_DBG, "%s: Request Regions failed - %x \n", __FUNCTION__, ret);
+		pci_disable_device(pdev);
+		return -ENODEV;
 	}
 
 	dev = alloc_etherdev(sizeof(struct s2io_nic));
@@ -7434,9 +7313,6 @@ s2io_init_nic(struct pci_dev *pdev, cons
 		case INTA:
 		    DBG_PRINT(ERR_DBG, "%s: Interrupt type INTA\n", dev->name);
 		    break;
-		case MSI:
-		    DBG_PRINT(ERR_DBG, "%s: Interrupt type MSI\n", dev->name);
-		    break;
 		case MSI_X:
 		    DBG_PRINT(ERR_DBG, "%s: Interrupt type MSI-X\n", dev->name);
 		    break;
@@ -7476,14 +7352,7 @@ s2io_init_nic(struct pci_dev *pdev, cons
       mem_alloc_failed:
 	free_shared_mem(sp);
 	pci_disable_device(pdev);
-	if (dev_intr_type != MSI_X)
-		pci_release_regions(pdev);
-	else {
-		release_mem_region(pci_resource_start(pdev, 0),
-			pci_resource_len(pdev, 0));
-		release_mem_region(pci_resource_start(pdev, 2),
-			pci_resource_len(pdev, 2));
-	}
+	pci_release_regions(pdev);
 	pci_set_drvdata(pdev, NULL);
 	free_netdev(dev);
 
@@ -7518,14 +7387,7 @@ static void __devexit s2io_rem_nic(struc
 	free_shared_mem(sp);
 	iounmap(sp->bar0);
 	iounmap(sp->bar1);
-	if (sp->intr_type != MSI_X)
-		pci_release_regions(pdev);
-	else {
-		release_mem_region(pci_resource_start(pdev, 0),
-			pci_resource_len(pdev, 0));
-		release_mem_region(pci_resource_start(pdev, 2),
-			pci_resource_len(pdev, 2));
-	}
+	pci_release_regions(pdev);
 	pci_set_drvdata(pdev, NULL);
 	free_netdev(dev);
 	pci_disable_device(pdev);
diff -urpN patch_1/drivers/net/s2io.h patch_2/drivers/net/s2io.h
--- patch_1/drivers/net/s2io.h	2007-07-19 14:20:53.000000000 +0530
+++ patch_2/drivers/net/s2io.h	2007-07-19 14:43:39.000000000 +0530
@@ -875,7 +875,6 @@ struct s2io_nic {
 	u16		lro_max_aggr_per_sess;
 
 #define INTA	0
-#define MSI	1
 #define MSI_X	2
 	u8 intr_type;
 
@@ -1019,8 +1018,6 @@ static int s2io_poll(struct net_device *
 static void s2io_init_pci(struct s2io_nic * sp);
 static int s2io_set_mac_addr(struct net_device *dev, u8 * addr);
 static void s2io_alarm_handle(unsigned long data);
-static int s2io_enable_msi(struct s2io_nic *nic);
-static irqreturn_t s2io_msi_handle(int irq, void *dev_id);
 static irqreturn_t
 s2io_msix_ring_handle(int irq, void *dev_id);
 static irqreturn_t


^ permalink raw reply

* [PATCH 2.6.22 1/4]S2IO: Removing 3 buffer mode support from the driver
From: Veena Parat @ 2007-07-23  6:20 UTC (permalink / raw)
  To: netdev, jeff; +Cc: support

 - Removed 3 buffer mode support from driver - unused feature
 - Incorporated Jeff Garzik's comments on elimination of inline typecasting
 - Code cleanup : Removed a few extra spaces

Signed-off-by: Veena Parat <veena.parat@neterion.com>
---
diff -urpN org/drivers/net/s2io.c patch_1/drivers/net/s2io.c
--- org/drivers/net/s2io.c	2007-07-17 15:05:49.000000000 +0530
+++ patch_1/drivers/net/s2io.c	2007-07-19 14:20:53.000000000 +0530
@@ -32,7 +32,7 @@
  * rx_ring_sz: This defines the number of receive blocks each ring can have.
  *     This is also an array of size 8.
  * rx_ring_mode: This defines the operation mode of all 8 rings. The valid
- *		values are 1, 2 and 3.
+ *		values are 1, 2.
  * tx_fifo_num: This defines the number of Tx FIFOs thats used int the driver.
  * tx_fifo_len: This too is an array of 8. Each element defines the number of
  * Tx descriptors that can be associated with each corresponding FIFO.
@@ -90,8 +90,8 @@
 static char s2io_driver_name[] = "Neterion";
 static char s2io_driver_version[] = DRV_VERSION;
 
-static int rxd_size[4] = {32,48,48,64};
-static int rxd_count[4] = {127,85,85,63};
+static int rxd_size[2] = {32,48};
+static int rxd_count[2] = {127,85};
 
 static inline int RXD_IS_UP2DT(struct RxD_t *rxdp)
 {
@@ -701,7 +701,7 @@ static int init_shared_mem(struct s2io_n
 			    (u64) tmp_p_addr_next;
 		}
 	}
-	if (nic->rxd_mode >= RXD_MODE_3A) {
+	if (nic->rxd_mode == RXD_MODE_3B) {
 		/*
 		 * Allocation of Storages for buffer addresses in 2BUFF mode
 		 * and the buffers as well.
@@ -870,7 +870,7 @@ static void free_shared_mem(struct s2io_
 		}
 	}
 
-	if (nic->rxd_mode >= RXD_MODE_3A) {
+	if (nic->rxd_mode == RXD_MODE_3B) {
 		/* Freeing buffer storage addresses in 2BUFF mode. */
 		for (i = 0; i < config->rx_ring_num; i++) {
 			blk_cnt = config->rx_cfg[i].num_rxd /
@@ -2233,44 +2233,6 @@ static void stop_nic(struct s2io_nic *ni
 	writeq(val64, &bar0->adapter_control);
 }
 
-static int fill_rxd_3buf(struct s2io_nic *nic, struct RxD_t *rxdp, struct \
-				sk_buff *skb)
-{
-	struct net_device *dev = nic->dev;
-	struct sk_buff *frag_list;
-	void *tmp;
-
-	/* Buffer-1 receives L3/L4 headers */
-	((struct RxD3*)rxdp)->Buffer1_ptr = pci_map_single
-			(nic->pdev, skb->data, l3l4hdr_size + 4,
-			PCI_DMA_FROMDEVICE);
-
-	/* skb_shinfo(skb)->frag_list will have L4 data payload */
-	skb_shinfo(skb)->frag_list = dev_alloc_skb(dev->mtu + ALIGN_SIZE);
-	if (skb_shinfo(skb)->frag_list == NULL) {
-		nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++;
-		DBG_PRINT(INFO_DBG, "%s: dev_alloc_skb failed\n ", dev->name);
-		return -ENOMEM ;
-	}
-	frag_list = skb_shinfo(skb)->frag_list;
-	skb->truesize += frag_list->truesize;
-	nic->mac_control.stats_info->sw_stat.mem_allocated 
-		+= frag_list->truesize;
-	frag_list->next = NULL;
-	tmp = (void *)ALIGN((long)frag_list->data, ALIGN_SIZE + 1);
-	frag_list->data = tmp;
-	skb_reset_tail_pointer(frag_list);
-
-	/* Buffer-2 receives L4 data payload */
-	((struct RxD3*)rxdp)->Buffer2_ptr = pci_map_single(nic->pdev,
-				frag_list->data, dev->mtu,
-				PCI_DMA_FROMDEVICE);
-	rxdp->Control_2 |= SET_BUFFER1_SIZE_3(l3l4hdr_size + 4);
-	rxdp->Control_2 |= SET_BUFFER2_SIZE_3(dev->mtu);
-
-	return SUCCESS;
-}
-
 /**
  *  fill_rx_buffers - Allocates the Rx side skbs
  *  @nic:  device private variable
@@ -2307,6 +2269,8 @@ static int fill_rx_buffers(struct s2io_n
 	unsigned long flags;
 	struct RxD_t *first_rxdp = NULL;
 	u64 Buffer0_ptr = 0, Buffer1_ptr = 0;
+	struct RxD1 *rxdp1;
+	struct RxD3 *rxdp3;
 
 	mac_control = &nic->mac_control;
 	config = &nic->config;
@@ -2359,7 +2323,7 @@ static int fill_rx_buffers(struct s2io_n
 			(block_no * (rxd_count[nic->rxd_mode] + 1)) + off;
 		}
 		if ((rxdp->Control_1 & RXD_OWN_XENA) &&
-			((nic->rxd_mode >= RXD_MODE_3A) &&
+			((nic->rxd_mode == RXD_MODE_3B) &&
 				(rxdp->Control_2 & BIT(0)))) {
 			mac_control->rings[ring_no].rx_curr_put_info.
 					offset = off;
@@ -2370,10 +2334,8 @@ static int fill_rx_buffers(struct s2io_n
 				HEADER_802_2_SIZE + HEADER_SNAP_SIZE;
 		if (nic->rxd_mode == RXD_MODE_1)
 			size += NET_IP_ALIGN;
-		else if (nic->rxd_mode == RXD_MODE_3B)
-			size = dev->mtu + ALIGN_SIZE + BUF0_LEN + 4;
 		else
-			size = l3l4hdr_size + ALIGN_SIZE + BUF0_LEN + 4;
+			size = dev->mtu + ALIGN_SIZE + BUF0_LEN + 4;
 
 		/* allocate skb */
 		skb = dev_alloc_skb(size);
@@ -2392,33 +2354,30 @@ static int fill_rx_buffers(struct s2io_n
 			+= skb->truesize;
 		if (nic->rxd_mode == RXD_MODE_1) {
 			/* 1 buffer mode - normal operation mode */
+			rxdp1 = (struct RxD1*)rxdp;
 			memset(rxdp, 0, sizeof(struct RxD1));
 			skb_reserve(skb, NET_IP_ALIGN);
-			((struct RxD1*)rxdp)->Buffer0_ptr = pci_map_single
+			rxdp1->Buffer0_ptr = pci_map_single
 			    (nic->pdev, skb->data, size - NET_IP_ALIGN,
 				PCI_DMA_FROMDEVICE);
 			rxdp->Control_2 = 
 				SET_BUFFER0_SIZE_1(size - NET_IP_ALIGN);
 
-		} else if (nic->rxd_mode >= RXD_MODE_3A) {
+		} else if (nic->rxd_mode == RXD_MODE_3B) {
 			/*
-			 * 2 or 3 buffer mode -
-			 * Both 2 buffer mode and 3 buffer mode provides 128
+			 * 2 buffer mode -
+			 * 2 buffer mode provides 128
 			 * byte aligned receive buffers.
-			 *
-			 * 3 buffer mode provides header separation where in
-			 * skb->data will have L3/L4 headers where as
-			 * skb_shinfo(skb)->frag_list will have the L4 data
-			 * payload
 			 */
 
+			rxdp3 = (struct RxD3*)rxdp;
 			/* save buffer pointers to avoid frequent dma mapping */
-			Buffer0_ptr = ((struct RxD3*)rxdp)->Buffer0_ptr;
-			Buffer1_ptr = ((struct RxD3*)rxdp)->Buffer1_ptr;
+			Buffer0_ptr = rxdp3->Buffer0_ptr;
+			Buffer1_ptr = rxdp3->Buffer1_ptr;
 			memset(rxdp, 0, sizeof(struct RxD3));
 			/* restore the buffer pointers for dma sync*/
-			((struct RxD3*)rxdp)->Buffer0_ptr = Buffer0_ptr;
-			((struct RxD3*)rxdp)->Buffer1_ptr = Buffer1_ptr;
+			rxdp3->Buffer0_ptr = Buffer0_ptr;
+			rxdp3->Buffer1_ptr = Buffer1_ptr;
 
 			ba = &mac_control->rings[ring_no].ba[block_no][off];
 			skb_reserve(skb, BUF0_LEN);
@@ -2428,13 +2387,13 @@ static int fill_rx_buffers(struct s2io_n
 			skb->data = (void *) (unsigned long)tmp;
 			skb_reset_tail_pointer(skb);
 
-			if (!(((struct RxD3*)rxdp)->Buffer0_ptr))
-				((struct RxD3*)rxdp)->Buffer0_ptr =
+			if (!(rxdp3->Buffer0_ptr))
+				rxdp3->Buffer0_ptr =
 				   pci_map_single(nic->pdev, ba->ba_0, BUF0_LEN,
 					   PCI_DMA_FROMDEVICE);
 			else
 				pci_dma_sync_single_for_device(nic->pdev,
-				(dma_addr_t) ((struct RxD3*)rxdp)->Buffer0_ptr,
+				(dma_addr_t) rxdp3->Buffer0_ptr,
 				    BUF0_LEN, PCI_DMA_FROMDEVICE);
 			rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN);
 			if (nic->rxd_mode == RXD_MODE_3B) {
@@ -2444,13 +2403,13 @@ static int fill_rx_buffers(struct s2io_n
 				 * Buffer2 will have L3/L4 header plus
 				 * L4 payload
 				 */
-				((struct RxD3*)rxdp)->Buffer2_ptr = pci_map_single
+				rxdp3->Buffer2_ptr = pci_map_single
 				(nic->pdev, skb->data, dev->mtu + 4,
 						PCI_DMA_FROMDEVICE);
 
 				/* Buffer-1 will be dummy buffer. Not used */
-				if (!(((struct RxD3*)rxdp)->Buffer1_ptr)) {
-					((struct RxD3*)rxdp)->Buffer1_ptr =
+				if (!(rxdp3->Buffer1_ptr)) {
+					rxdp3->Buffer1_ptr =
 						pci_map_single(nic->pdev,
 						ba->ba_1, BUF1_LEN,
 						PCI_DMA_FROMDEVICE);
@@ -2458,19 +2417,6 @@ static int fill_rx_buffers(struct s2io_n
 				rxdp->Control_2 |= SET_BUFFER1_SIZE_3(1);
 				rxdp->Control_2 |= SET_BUFFER2_SIZE_3
 								(dev->mtu + 4);
-			} else {
-				/* 3 buffer mode */
-				if (fill_rxd_3buf(nic, rxdp, skb) == -ENOMEM) {
-					nic->mac_control.stats_info->sw_stat.\
-					mem_freed += skb->truesize;
-					dev_kfree_skb_irq(skb);
-					if (first_rxdp) {
-						wmb();
-						first_rxdp->Control_1 |=
-							RXD_OWN_XENA;
-					}
-					return -ENOMEM ;
-				}
 			}
 			rxdp->Control_2 |= BIT(0);
 		}
@@ -2515,6 +2461,8 @@ static void free_rxd_blk(struct s2io_nic
 	struct RxD_t *rxdp;
 	struct mac_info *mac_control;
 	struct buffAdd *ba;
+	struct RxD1 *rxdp1;
+	struct RxD3 *rxdp3;
 
 	mac_control = &sp->mac_control;
 	for (j = 0 ; j < rxd_count[sp->rxd_mode]; j++) {
@@ -2526,40 +2474,30 @@ static void free_rxd_blk(struct s2io_nic
 			continue;
 		}
 		if (sp->rxd_mode == RXD_MODE_1) {
+			rxdp1 = (struct RxD1*)rxdp;
 			pci_unmap_single(sp->pdev, (dma_addr_t)
-				 ((struct RxD1*)rxdp)->Buffer0_ptr,
-				 dev->mtu +
-				 HEADER_ETHERNET_II_802_3_SIZE
-				 + HEADER_802_2_SIZE +
-				 HEADER_SNAP_SIZE,
-				 PCI_DMA_FROMDEVICE);
+				rxdp1->Buffer0_ptr,
+				dev->mtu +
+				HEADER_ETHERNET_II_802_3_SIZE
+				+ HEADER_802_2_SIZE +
+				HEADER_SNAP_SIZE,
+				PCI_DMA_FROMDEVICE);
 			memset(rxdp, 0, sizeof(struct RxD1));
 		} else if(sp->rxd_mode == RXD_MODE_3B) {
+			rxdp3 = (struct RxD3*)rxdp;
 			ba = &mac_control->rings[ring_no].
 				ba[blk][j];
 			pci_unmap_single(sp->pdev, (dma_addr_t)
-				 ((struct RxD3*)rxdp)->Buffer0_ptr,
-				 BUF0_LEN,
-				 PCI_DMA_FROMDEVICE);
-			pci_unmap_single(sp->pdev, (dma_addr_t)
-				 ((struct RxD3*)rxdp)->Buffer1_ptr,
-				 BUF1_LEN,
-				 PCI_DMA_FROMDEVICE);
-			pci_unmap_single(sp->pdev, (dma_addr_t)
-				 ((struct RxD3*)rxdp)->Buffer2_ptr,
-				 dev->mtu + 4,
-				 PCI_DMA_FROMDEVICE);
-			memset(rxdp, 0, sizeof(struct RxD3));
-		} else {
-			pci_unmap_single(sp->pdev, (dma_addr_t)
-				((struct RxD3*)rxdp)->Buffer0_ptr, BUF0_LEN,
+				rxdp3->Buffer0_ptr,
+				BUF0_LEN,
 				PCI_DMA_FROMDEVICE);
 			pci_unmap_single(sp->pdev, (dma_addr_t)
-				((struct RxD3*)rxdp)->Buffer1_ptr,
-				l3l4hdr_size + 4,
+				rxdp3->Buffer1_ptr,
+				BUF1_LEN,
 				PCI_DMA_FROMDEVICE);
 			pci_unmap_single(sp->pdev, (dma_addr_t)
-				((struct RxD3*)rxdp)->Buffer2_ptr, dev->mtu,
+				rxdp3->Buffer2_ptr,
+				dev->mtu + 4,
 				PCI_DMA_FROMDEVICE);
 			memset(rxdp, 0, sizeof(struct RxD3));
 		}
@@ -2756,6 +2694,8 @@ static void rx_intr_handler(struct ring_
 	struct sk_buff *skb;
 	int pkt_cnt = 0;
 	int i;
+	struct RxD1* rxdp1;
+	struct RxD3* rxdp3;
 
 	spin_lock(&nic->rx_lock);
 	if (atomic_read(&nic->card_state) == CARD_DOWN) {
@@ -2796,32 +2736,23 @@ static void rx_intr_handler(struct ring_
 			return;
 		}
 		if (nic->rxd_mode == RXD_MODE_1) {
+			rxdp1 = (struct RxD1*)rxdp;
 			pci_unmap_single(nic->pdev, (dma_addr_t)
-				 ((struct RxD1*)rxdp)->Buffer0_ptr,
-				 dev->mtu +
-				 HEADER_ETHERNET_II_802_3_SIZE +
-				 HEADER_802_2_SIZE +
-				 HEADER_SNAP_SIZE,
-				 PCI_DMA_FROMDEVICE);
+				rxdp1->Buffer0_ptr,
+				dev->mtu +
+				HEADER_ETHERNET_II_802_3_SIZE +
+				HEADER_802_2_SIZE +
+				HEADER_SNAP_SIZE,
+				PCI_DMA_FROMDEVICE);
 		} else if (nic->rxd_mode == RXD_MODE_3B) {
+			rxdp3 = (struct RxD3*)rxdp;
 			pci_dma_sync_single_for_cpu(nic->pdev, (dma_addr_t)
-				 ((struct RxD3*)rxdp)->Buffer0_ptr,
-				 BUF0_LEN, PCI_DMA_FROMDEVICE);
-			pci_unmap_single(nic->pdev, (dma_addr_t)
-				 ((struct RxD3*)rxdp)->Buffer2_ptr,
-				 dev->mtu + 4,
-				 PCI_DMA_FROMDEVICE);
-		} else {
-			pci_dma_sync_single_for_cpu(nic->pdev, (dma_addr_t)
-					 ((struct RxD3*)rxdp)->Buffer0_ptr, BUF0_LEN,
-					 PCI_DMA_FROMDEVICE);
+				rxdp3->Buffer0_ptr,
+				BUF0_LEN, PCI_DMA_FROMDEVICE);
 			pci_unmap_single(nic->pdev, (dma_addr_t)
-					 ((struct RxD3*)rxdp)->Buffer1_ptr,
-					 l3l4hdr_size + 4,
-					 PCI_DMA_FROMDEVICE);
-			pci_unmap_single(nic->pdev, (dma_addr_t)
-					 ((struct RxD3*)rxdp)->Buffer2_ptr,
-					 dev->mtu, PCI_DMA_FROMDEVICE);
+				rxdp3->Buffer2_ptr,
+				dev->mtu + 4,
+				PCI_DMA_FROMDEVICE);
 		}
 		prefetch(skb->data);
 		rx_osm_handler(ring_data, rxdp);
@@ -4927,8 +4858,6 @@ static void s2io_ethtool_gringparam(stru
 		ering->rx_max_pending = MAX_RX_DESC_1;
 	else if (sp->rxd_mode == RXD_MODE_3B)
 		ering->rx_max_pending = MAX_RX_DESC_2;
-	else if (sp->rxd_mode == RXD_MODE_3A)
-		ering->rx_max_pending = MAX_RX_DESC_3;
 
 	ering->tx_max_pending = MAX_TX_DESC;
 	for (i = 0 ; i < sp->config.tx_fifo_num ; i++) {
@@ -6266,9 +6195,9 @@ static int set_rxd_buffer_pointer(struct
 				u64 *temp2, int size)
 {
 	struct net_device *dev = sp->dev;
-	struct sk_buff *frag_list;
 
 	if ((sp->rxd_mode == RXD_MODE_1) && (rxdp->Host_Control == 0)) {
+		struct RxD1 *rxdp1 = (struct RxD1 *)rxdp;
 		/* allocate skb */
 		if (*skb) {
 			DBG_PRINT(INFO_DBG, "SKB is not NULL\n");
@@ -6277,7 +6206,7 @@ static int set_rxd_buffer_pointer(struct
 			 * using same mapped address for the Rxd
 			 * buffer pointer
 			 */
-			((struct RxD1*)rxdp)->Buffer0_ptr = *temp0;
+			rxdp1->Buffer0_ptr = *temp0;
 		} else {
 			*skb = dev_alloc_skb(size);
 			if (!(*skb)) {
@@ -6294,18 +6223,19 @@ static int set_rxd_buffer_pointer(struct
 			 * such it will be used for next rxd whose
 			 * Host Control is NULL
 			 */
-			((struct RxD1*)rxdp)->Buffer0_ptr = *temp0 =
+			rxdp1->Buffer0_ptr = *temp0 =
 				pci_map_single( sp->pdev, (*skb)->data,
 					size - NET_IP_ALIGN,
 					PCI_DMA_FROMDEVICE);
 			rxdp->Host_Control = (unsigned long) (*skb);
 		}
 	} else if ((sp->rxd_mode == RXD_MODE_3B) && (rxdp->Host_Control == 0)) {
+		struct RxD3 *rxdp3 = (struct RxD3 *)rxdp;
 		/* Two buffer Mode */
 		if (*skb) {
-			((struct RxD3*)rxdp)->Buffer2_ptr = *temp2;
-			((struct RxD3*)rxdp)->Buffer0_ptr = *temp0;
-			((struct RxD3*)rxdp)->Buffer1_ptr = *temp1;
+			rxdp3->Buffer2_ptr = *temp2;
+			rxdp3->Buffer0_ptr = *temp0;
+			rxdp3->Buffer1_ptr = *temp1;
 		} else {
 			*skb = dev_alloc_skb(size);
 			if (!(*skb)) {
@@ -6318,69 +6248,19 @@ static int set_rxd_buffer_pointer(struct
 			}
 			sp->mac_control.stats_info->sw_stat.mem_allocated 
 				+= (*skb)->truesize;
-			((struct RxD3*)rxdp)->Buffer2_ptr = *temp2 =
+			rxdp3->Buffer2_ptr = *temp2 =
 				pci_map_single(sp->pdev, (*skb)->data,
 					       dev->mtu + 4,
 					       PCI_DMA_FROMDEVICE);
-			((struct RxD3*)rxdp)->Buffer0_ptr = *temp0 =
+			rxdp3->Buffer0_ptr = *temp0 =
 				pci_map_single( sp->pdev, ba->ba_0, BUF0_LEN,
 						PCI_DMA_FROMDEVICE);
 			rxdp->Host_Control = (unsigned long) (*skb);
 
 			/* Buffer-1 will be dummy buffer not used */
-			((struct RxD3*)rxdp)->Buffer1_ptr = *temp1 =
+			rxdp3->Buffer1_ptr = *temp1 =
 				pci_map_single(sp->pdev, ba->ba_1, BUF1_LEN,
-					       PCI_DMA_FROMDEVICE);
-		}
-	} else if ((rxdp->Host_Control == 0)) {
-		/* Three buffer mode */
-		if (*skb) {
-			((struct RxD3*)rxdp)->Buffer0_ptr = *temp0;
-			((struct RxD3*)rxdp)->Buffer1_ptr = *temp1;
-			((struct RxD3*)rxdp)->Buffer2_ptr = *temp2;
-		} else {
-			*skb = dev_alloc_skb(size);
-			if (!(*skb)) {
-				DBG_PRINT(INFO_DBG, "%s: Out of ", dev->name);
-				DBG_PRINT(INFO_DBG, "memory to allocate ");
-				DBG_PRINT(INFO_DBG, "3 buf mode SKBs\n");
-				sp->mac_control.stats_info->sw_stat. \
-					mem_alloc_fail_cnt++;
-				return -ENOMEM;
-			}
-			sp->mac_control.stats_info->sw_stat.mem_allocated 
-				+= (*skb)->truesize;
-			((struct RxD3*)rxdp)->Buffer0_ptr = *temp0 =
-				pci_map_single(sp->pdev, ba->ba_0, BUF0_LEN,
-					       PCI_DMA_FROMDEVICE);
-			/* Buffer-1 receives L3/L4 headers */
-			((struct RxD3*)rxdp)->Buffer1_ptr = *temp1 =
-				pci_map_single( sp->pdev, (*skb)->data,
-						l3l4hdr_size + 4,
 						PCI_DMA_FROMDEVICE);
-			/*
-			 * skb_shinfo(skb)->frag_list will have L4
-			 * data payload
-			 */
-			skb_shinfo(*skb)->frag_list = dev_alloc_skb(dev->mtu +
-								   ALIGN_SIZE);
-			if (skb_shinfo(*skb)->frag_list == NULL) {
-				DBG_PRINT(ERR_DBG, "%s: dev_alloc_skb \
-					  failed\n ", dev->name);
-				sp->mac_control.stats_info->sw_stat. \
-					mem_alloc_fail_cnt++;
-				return -ENOMEM ;
-			}
-			frag_list = skb_shinfo(*skb)->frag_list;
-			frag_list->next = NULL;
-			sp->mac_control.stats_info->sw_stat.mem_allocated 
-				+= frag_list->truesize;
-			/*
-			 * Buffer-2 receives L4 data payload
-			 */
-			((struct RxD3*)rxdp)->Buffer2_ptr = *temp2 =
-				pci_map_single( sp->pdev, frag_list->data,
-						dev->mtu, PCI_DMA_FROMDEVICE);
 		}
 	}
 	return 0;
@@ -6395,10 +6275,6 @@ static void set_rxd_buffer_size(struct s
 		rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN);
 		rxdp->Control_2 |= SET_BUFFER1_SIZE_3(1);
 		rxdp->Control_2 |= SET_BUFFER2_SIZE_3( dev->mtu + 4);
-	} else {
-		rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN);
-		rxdp->Control_2 |= SET_BUFFER1_SIZE_3(l3l4hdr_size + 4);
-		rxdp->Control_2 |= SET_BUFFER2_SIZE_3(dev->mtu);
 	}
 }
 
@@ -6420,8 +6296,6 @@ static  int rxd_owner_bit_reset(struct s
 		size += NET_IP_ALIGN;
 	else if (sp->rxd_mode == RXD_MODE_3B)
 		size = dev->mtu + ALIGN_SIZE + BUF0_LEN + 4;
-	else
-		size = l3l4hdr_size + ALIGN_SIZE + BUF0_LEN + 4;
 
 	for (i = 0; i < config->rx_ring_num; i++) {
 		blk_cnt = config->rx_cfg[i].num_rxd /
@@ -6431,7 +6305,7 @@ static  int rxd_owner_bit_reset(struct s
 			for (k = 0; k < rxd_count[sp->rxd_mode]; k++) {
 				rxdp = mac_control->rings[i].
 					rx_blocks[j].rxds[k].virt_addr;
-				if(sp->rxd_mode >= RXD_MODE_3A)
+				if(sp->rxd_mode == RXD_MODE_3B)
 					ba = &mac_control->rings[i].ba[j][k];
 				if (set_rxd_buffer_pointer(sp, rxdp, ba,
 						       &skb,(u64 *)&temp0_64,
@@ -6914,7 +6788,7 @@ static int rx_osm_handler(struct ring_in
 		sp->stats.rx_bytes += len;
 		skb_put(skb, len);
 
-	} else if (sp->rxd_mode >= RXD_MODE_3A) {
+	} else if (sp->rxd_mode == RXD_MODE_3B) {
 		int get_block = ring_data->rx_curr_get_info.block_index;
 		int get_off = ring_data->rx_curr_get_info.offset;
 		int buf0_len = RXD_GET_BUFFER0_SIZE_3(rxdp->Control_2);
@@ -6924,18 +6798,7 @@ static int rx_osm_handler(struct ring_in
 		struct buffAdd *ba = &ring_data->ba[get_block][get_off];
 		sp->stats.rx_bytes += buf0_len + buf2_len;
 		memcpy(buff, ba->ba_0, buf0_len);
-
-		if (sp->rxd_mode == RXD_MODE_3A) {
-			int buf1_len = RXD_GET_BUFFER1_SIZE_3(rxdp->Control_2);
-
-			skb_put(skb, buf1_len);
-			skb->len += buf2_len;
-			skb->data_len += buf2_len;
-			skb_put(skb_shinfo(skb)->frag_list, buf2_len);
-			sp->stats.rx_bytes += buf1_len;
-
-		} else
-			skb_put(skb, buf2_len);
+		skb_put(skb, buf2_len);
 	}
 
 	if ((rxdp->Control_1 & TCP_OR_UDP_FRAME) && ((!sp->lro) ||
@@ -7145,10 +7008,10 @@ static int s2io_verify_parm(struct pci_d
 		*dev_intr_type = INTA;
 	}
 
-	if (rx_ring_mode > 3) {
+	if ((rx_ring_mode != 1) && (rx_ring_mode != 2)) {
 		DBG_PRINT(ERR_DBG, "s2io: Requested ring mode not supported\n");
-		DBG_PRINT(ERR_DBG, "s2io: Defaulting to 3-buffer mode\n");
-		rx_ring_mode = 3;
+		DBG_PRINT(ERR_DBG, "s2io: Defaulting to 1-buffer mode\n");
+		rx_ring_mode = 1;
 	}
 	return SUCCESS;
 }
@@ -7288,8 +7151,6 @@ s2io_init_nic(struct pci_dev *pdev, cons
 		sp->rxd_mode = RXD_MODE_1;
 	if (rx_ring_mode == 2)
 		sp->rxd_mode = RXD_MODE_3B;
-	if (rx_ring_mode == 3)
-		sp->rxd_mode = RXD_MODE_3A;
 
 	sp->intr_type = dev_intr_type;
 
@@ -7565,10 +7426,6 @@ s2io_init_nic(struct pci_dev *pdev, cons
 		    DBG_PRINT(ERR_DBG, "%s: 2-Buffer receive mode enabled\n",
 						dev->name);
 		    break;
-		case RXD_MODE_3A:
-		    DBG_PRINT(ERR_DBG, "%s: 3-Buffer receive mode enabled\n",
-						dev->name);
-		    break;
 	}
 
 	if (napi)
diff -urpN org/drivers/net/s2io.h patch_1/drivers/net/s2io.h
--- org/drivers/net/s2io.h	2007-07-17 15:05:49.000000000 +0530
+++ patch_1/drivers/net/s2io.h	2007-07-19 14:20:53.000000000 +0530
@@ -575,8 +575,7 @@ struct RxD_block {
 #define SIZE_OF_BLOCK	4096
 
 #define RXD_MODE_1	0 /* One Buffer mode */
-#define RXD_MODE_3A	1 /* Three Buffer mode */
-#define RXD_MODE_3B	2 /* Two Buffer mode */
+#define RXD_MODE_3B	1 /* Two Buffer mode */
 
 /* Structure to hold virtual addresses of Buf0 and Buf1 in
  * 2buf mode. */


^ permalink raw reply

* [ofa-general] Re: [PATCH 02/10] Networking include file changes.
From: Sridhar Samudrala @ 2007-07-23  5:59 UTC (permalink / raw)
  To: Krishna Kumar2
  Cc: jagana, johnpol, herbert, gaagaan, Robert.Olsson, kumarkr,
	mcarlson, peter.p.waskiewicz.jr, hadi, kaber, jeff, general,
	mchan, tgraf, netdev, davem, rdreier
In-Reply-To: <OF46F8CFAE.90A18F30-ON6525731F.0023182A-6525731F.0023B8DF@in.ibm.com>

Krishna Kumar2 wrote:
> Hi Sridhar,
> 
> Sridhar Samudrala <sri@us.ibm.com> wrote on 07/20/2007 10:55:05 PM:
>>> diff -ruNp org/include/net/pkt_sched.h new/include/net/pkt_sched.h
>>> --- org/include/net/pkt_sched.h   2007-07-20 07:49:28.000000000 +0530
>>> +++ new/include/net/pkt_sched.h   2007-07-20 08:30:22.000000000 +0530
>>> @@ -80,13 +80,13 @@ extern struct qdisc_rate_table *qdisc_ge
>>>        struct rtattr *tab);
>>>  extern void qdisc_put_rtab(struct qdisc_rate_table *tab);
>>>
>>> -extern void __qdisc_run(struct net_device *dev);
>>> +extern void __qdisc_run(struct net_device *dev, struct sk_buff_head
> *blist);
>> Why do we need this additional 'blist' argument?
>> Is this different from dev->skb_blist?
> 
> It is the same, but I want to call it mostly with NULL and rarely with the
> batch list pointer (so it is related to your other question). My original
> code didn't have this and was trying batching in all cases. But in most
> xmit's (probably almost all), there will be only one packet in the queue to
> send and batching will never happen. When there is a lock contention or if
> the queue is stopped, then the next iteration will find >1 packets. But I
> still will try no batching for the lock failure case as there be probably
> 2 packets (one from previous time and 1 from this time, or 3 if two
> failures,
> etc), and try batching only when queue was stopped from net_tx_action (this
> was based on Dave Miller's idea).


Is this right to say that the above change is to get this behavior?
   If qdisc_run() is called from dev_queue_xmit() don't use batching.
   If qdisc_run() is called from net_tx_action(), do batching.

Isn't it possible to have multiple skb's in the qdisc queue in the
first case?

If this additional argument is used to indicate if we should do batching
or not, then passing a flag may be much more cleaner than passing the blist.

Thanks
Sridhar

^ permalink raw reply

* Re: 2.6.20->2.6.21 - networking dies after random time
From: Marcin Ślusarz @ 2007-07-23  5:44 UTC (permalink / raw)
  To: Jarek Poplawski, Jean-Baptiste Vignaud, linux-kernel, shemminger,
	linux-net, netdev, Ingo Molnar, Thomas Gleixner, Andrew Morton,
	Linus Torvalds
In-Reply-To: <20070629150759.GC2771@ff.dom.local>

Ok, I've bisected this problem and found that this patch broke my NIC:

76d2160147f43f982dfe881404cfde9fd0a9da21 is first bad commit
commit 76d2160147f43f982dfe881404cfde9fd0a9da21
Author: Ingo Molnar <mingo@elte.hu>
Date:   Fri Feb 16 01:28:24 2007 -0800

    [PATCH] genirq: do not mask interrupts by default

    Never mask interrupts immediately upon request.  Disabling interrupts in
    high-performance codepaths is rare, and on the other hand this change could
    recover lost edges (or even other types of lost interrupts) by
conservatively
    only masking interrupts after they happen.  (NOTE: with this change the
    highlevel irq-disable code still soft-disables this IRQ line - and
if such an
    interrupt happens then the IRQ flow handler keeps the IRQ masked.)

    Mark i8529A controllers as 'never loses an edge'.

    Signed-off-by: Ingo Molnar <mingo@elte.hu>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=76d2160147f43f982dfe881404cfde9fd0a9da21

After reverting it on top of 2.6.21.3 (with
d7e25f3394ba05a6d64cb2be42c2765fe72ea6b2 - [PATCH] genirq: remove
IRQ_DISABLED (which ment "remove IRQ_DELAYED_DISABLE")), the problem
didn't show up :)
(http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=d7e25f3394ba05a6d64cb2be42c2765fe72ea6b2)

So I cooked patch like below and everything is working fine (so far)

Fix default_disable interrupt function (broken by [PATCH] genirq: do
not mask interrupts by default) - revert removal of codepath which was
invoked when removed flag (IRQ_DELAYED_DISABLE) wag NOT set

Signed-off-by: Marcin Slusarz <marcin.slusarz@gmail.com>
---
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 76a9106..0bb23cd 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -230,6 +230,8 @@ static void default_enable(unsigned int irq)
  */
 static void default_disable(unsigned int irq)
 {
+	struct irq_desc *desc = irq_desc + irq;
+	desc->chip->mask(irq);
 }

 /*

(Sorry for whitespace damage, but I have to send it from webmail :|)
(I'm a kernel noob, so don't kill me if my patch is wrong ;)
ps: Here is the beginning of this thread: http://lkml.org/lkml/2007/6/16/182


Regards,
Marcin Slusarz

^ permalink raw reply related

* [ofa-general] Re: [PATCH 00/10] Implement batching skb API
From: Krishna Kumar2 @ 2007-07-23  4:49 UTC (permalink / raw)
  To: hadi
  Cc: jagana, johnpol, gaagaan, jeff, Robert.Olsson, kumarkr, rdreier,
	peter.p.waskiewicz.jr, mcarlson, kaber, netdev, general, mchan,
	tgraf, sri, davem, herbert
In-Reply-To: <1185108670.5192.122.camel@localhost>

Hi Jamal,

J Hadi Salim <j.hadi123@gmail.com> wrote on 07/22/2007 06:21:09 PM:

> My concern is there is no consistency in results. I see improvements on
> something which you say dont. You see improvement in something that
> Evgeniy doesnt etc.

Hmmm ? Evgeniy has not even tested my code to find some regression :) And
you may possibly not find much improvement in E1000 when you run iperf
(which
is what I do) compared to pktgen. I can re-run and confirm this since my
last
E1000 run was quite some time back.

My point is that batching not being viable for E1000 (or tg3) need not be
the
sole criterea for inclusion. If IPoIB or other drivers can take advantage
of
it and get better results, then batching can be considered. Maybe E1000 too
can get improvements if some one with more expertise tries to add this API
(not judging your driver writing capabilities - just stating that driver
writers will know more knobs to exploit a complex device like E1000).

> > Since E1000 doesn't seem to use the TX lock on RX (atleast I couldn't
find
> > it),
> > I feel having prep will not help as no other cpu can execute the
queue/xmit
> > code anyway (E1000 is also a LLTX driver).
>
> My experiments show it is useful (in a very visible way using pktgen)
> for e1000 to have the prep() interface.

I meant : have you compared results of batching with prep on vs prep off,
and
what is the difference in BW ?

> >  Other driver that hold tx lock could get improvement however.
>
> So you do see the value then with non LLTX drivers, right? ;->

No. I see value only in non-LLTX drivers which also gets the same TX lock
in the RX path. If different locks are got by TX/RX, then since you are
holding queue_lock before calling 'prep', this excludes other TX from
running at the same time. In that case, pre-poning the get of the tx_lock
to do the 'prep' will not cause any degradation (since no other tx can run
anyway, while rx can run as it gets a different lock).

> The value is also there in LLTX drivers even if in just formating a skb
> ready for transmit. If this is not clear i could do a much longer
> writeup on my thought evolution towards adding prep().

In LLTX drivers, the driver does the 'prep' without holding the tx_lock in
any case, so there should be no improvement. Could you send the write-up
since
I really don't see the value in prep unless the driver is non-LLTX *and*
TX/RX holds the same TX lock. I think that is the sole criterea, right ?

> > If it helps, I guess you could send me a patch to
> > add that and I can also test it to see what the effect is. I didn't add
it
> > since IPoIB wouldn't be able to exploit it (unless someone is kind
enough
> > to show me how to).
>
> Such core code should not just be focussed on IPOIB.

There is *nothing* IPoIB specific or focus in my code. I said adding prep
doesn't
work for IPoIB and so it is pointless to add bloat to the code until some
code can
actually take advantage of this feature (I am sure you will agree). Which
is why I
also mentioned to please send me a patch if you find it useful for any
driver
rather than rejecting this idea.

> > I think the code I have is ready and stable,
>
> I am not sure how to intepret that - are you saying all-is-good and we
> should just push your code in?

I am only too well aware that Dave will not accept any code (having
experienced with Mobile IPv6 a long time back when he said to move most
of it to userspace and he was absolutely correct :). What I meant to say
is that there isn't much point in saying that your code is not ready or
you are using old code base, or has multiple restart functions, or is not
tested enough, etc, and then say let's re-do/rethink the whole
implementation when my code is already working and giving good results.
Unless you have some design issues with it, or code is written badly, is
not maintainable, not linux style compliant, is buggy, will not handle
some case/workload, type of issues.

OTOH, if you find some cases that are better handled with :
      1. prep handler
      2. xmit_win (which I don't have now),
then please send me patches and I will also test out and incorporate.

> It sounds disingenuous but i may have misread you.

("lacking in frankness, candor, or sincerity; falsely or hypocritically
ingenuous; insincere") ???? Sorry, no response to personal comments and
have a flame-war :)

Thanks,

- KK

^ permalink raw reply

* [PATCH 4/4] Initialize and fill IPv6 route age
From: Varun Chandramohan @ 2007-07-23  4:43 UTC (permalink / raw)
  To: netdev; +Cc: sri, dlstevens, varuncha

The age field of the ipv6 route structures are initilized with the current timeval at the time of route       creation. When the route dump is called the route age value stored in the structure is subtracted from the     present timeval and the difference is passed on as the route age.

Signed-off-by: Varun Chandramohan <varunc@linux.vnet.ibm.com>
---
 include/net/ip6_fib.h   |    1 +
 include/net/ip6_route.h |    3 +++
 net/ipv6/addrconf.c     |    5 +++++
 net/ipv6/route.c        |   23 +++++++++++++++++++----
 4 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index c48ea87..e30a1cf 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -98,6 +98,7 @@ struct rt6_info
 	
 	u32				rt6i_flags;
 	u32				rt6i_metric;
+	time_t				rt6i_age;
 	atomic_t			rt6i_ref;
 	struct fib6_table		*rt6i_table;
 
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index 5456fdd..fc9716c 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -36,6 +36,9 @@ struct route_info {
 #define RT6_LOOKUP_F_REACHABLE	0x2
 #define RT6_LOOKUP_F_HAS_SADDR	0x4
 
+#define RT6_SET_ROUTE_INFO 0x0
+#define RT6_GET_ROUTE_INFO 0x1
+
 extern struct rt6_info	ip6_null_entry;
 
 #ifdef CONFIG_IPV6_MULTIPLE_TABLES
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 5a5f8bd..715c766 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -4187,6 +4187,7 @@ EXPORT_SYMBOL(unregister_inet6addr_notif
 
 int __init addrconf_init(void)
 {
+	struct timeval tv;
 	int err = 0;
 
 	/* The addrconf netdev notifier requires that loopback_dev
@@ -4214,10 +4215,14 @@ int __init addrconf_init(void)
 	if (err)
 		return err;
 
+	do_gettimeofday(&tv);
 	ip6_null_entry.rt6i_idev = in6_dev_get(&loopback_dev);
+	ip6_null_entry.rt6i_age = timeval_to_sec(&tv);
 #ifdef CONFIG_IPV6_MULTIPLE_TABLES
 	ip6_prohibit_entry.rt6i_idev = in6_dev_get(&loopback_dev);
+	ip6_prohibit_entry.rt6i_age = timeval_to_sec(&tv);
 	ip6_blk_hole_entry.rt6i_idev = in6_dev_get(&loopback_dev);
+	ip6_blk_hole_entry.rt6i_age = timeval_to_sec(&tv);
 #endif
 
 	register_netdevice_notifier(&ipv6_dev_notf);
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index fe8d983..9386c05 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -600,7 +600,14 @@ static int __ip6_ins_rt(struct rt6_info
 {
 	int err;
 	struct fib6_table *table;
+	struct timeval tv;
 
+	do_gettimeofday(&tv);
+	/* Update the timeval for new routes
+	 * We add it here to make it common irrespective
+	 * of how the new route is added.
+	 */
+	rt->rt6i_age = timeval_to_sec(&tv);
 	table = rt->rt6i_table;
 	write_lock_bh(&table->tb6_lock);
 	err = fib6_add(&table->tb6_root, rt, info);
@@ -2111,6 +2118,7 @@ static inline size_t rt6_nlmsg_size(void
 	       + nla_total_size(4) /* RTA_IIF */
 	       + nla_total_size(4) /* RTA_OIF */
 	       + nla_total_size(4) /* RTA_PRIORITY */
+	       + nla_total_size(4) /*RTA_AGE*/
 	       + RTAX_MAX * nla_total_size(4) /* RTA_METRICS */
 	       + nla_total_size(sizeof(struct rta_cacheinfo));
 }
@@ -2118,10 +2126,11 @@ static inline size_t rt6_nlmsg_size(void
 static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
 			 struct in6_addr *dst, struct in6_addr *src,
 			 int iif, int type, u32 pid, u32 seq,
-			 int prefix, unsigned int flags)
+			 int prefix, unsigned int flags, int dumpflg)
 {
 	struct rtmsg *rtm;
 	struct nlmsghdr *nlh;
+	struct timeval tv;
 	long expires;
 	u32 table;
 
@@ -2185,6 +2194,12 @@ static int rt6_fill_node(struct sk_buff
 		if (ipv6_get_saddr(&rt->u.dst, dst, &saddr_buf) == 0)
 			NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf);
 	}
+	
+	do_gettimeofday(&tv);
+	if (dumpflg)
+		NLA_PUT_U32(skb, RTA_AGE, timeval_to_sec(&tv) - rt->rt6i_age);
+	else
+		NLA_PUT_U32(skb, RTA_AGE, rt->rt6i_age);
 
 	if (rtnetlink_put_metrics(skb, rt->u.dst.metrics) < 0)
 		goto nla_put_failure;
@@ -2222,7 +2237,7 @@ int rt6_dump_route(struct rt6_info *rt,
 
 	return rt6_fill_node(arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE,
 		     NETLINK_CB(arg->cb->skb).pid, arg->cb->nlh->nlmsg_seq,
-		     prefix, NLM_F_MULTI);
+		     prefix, NLM_F_MULTI, RT6_GET_ROUTE_INFO);
 }
 
 static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg)
@@ -2287,7 +2302,7 @@ static int inet6_rtm_getroute(struct sk_
 
 	err = rt6_fill_node(skb, rt, &fl.fl6_dst, &fl.fl6_src, iif,
 			    RTM_NEWROUTE, NETLINK_CB(in_skb).pid,
-			    nlh->nlmsg_seq, 0, 0);
+			    nlh->nlmsg_seq, 0, 0, RT6_GET_ROUTE_INFO);
 	if (err < 0) {
 		kfree_skb(skb);
 		goto errout;
@@ -2316,7 +2331,7 @@ void inet6_rt_notify(int event, struct r
 	if (skb == NULL)
 		goto errout;
 
-	err = rt6_fill_node(skb, rt, NULL, NULL, 0, event, pid, seq, 0, 0);
+	err = rt6_fill_node(skb, rt, NULL, NULL, 0, event, pid, seq, 0, 0, RT6_SET_ROUTE_INFO);
 	if (err < 0) {
 		/* -EMSGSIZE implies BUG in rt6_nlmsg_size() */
 		WARN_ON(err == -EMSGSIZE);
-- 
1.4.3.4


^ permalink raw reply related

* [PATCH 3/4] Initilize and populate age field
From: Varun Chandramohan @ 2007-07-23  4:42 UTC (permalink / raw)
  To: netdev; +Cc: sri, dlstevens, varuncha

The age field is filled with the current time at the time of creation of the route. When the routes are dumped
then the age value stored in the route structure is subtracted from the current time value and the difference is the age expressed in secs.

Signed-off-by: Varun Chandramohan <varunc@linux.vnet.ibm.com>
---
 net/ipv4/fib_hash.c      |    3 +++
 net/ipv4/fib_lookup.h    |    3 ++-
 net/ipv4/fib_semantics.c |   16 +++++++++++++---
 net/ipv4/fib_trie.c      |    1 +
 4 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c
index 07e843a..faa7364 100644
--- a/net/ipv4/fib_hash.c
+++ b/net/ipv4/fib_hash.c
@@ -448,6 +448,7 @@ static int fn_hash_insert(struct fib_tab
 			fa->fa_info = fi;
 			fa->fa_type = cfg->fc_type;
 			fa->fa_scope = cfg->fc_scope;
+			fa->fa_age = 0;
 			state = fa->fa_state;
 			fa->fa_state &= ~FA_S_ACCESSED;
 			fib_hash_genid++;
@@ -507,6 +508,7 @@ static int fn_hash_insert(struct fib_tab
 	new_fa->fa_type = cfg->fc_type;
 	new_fa->fa_scope = cfg->fc_scope;
 	new_fa->fa_state = 0;
+	new_fa->fa_age = 0;
 
 	/*
 	 * Insert new entry to the list.
@@ -697,6 +699,7 @@ fn_hash_dump_bucket(struct sk_buff *skb,
 					  f->fn_key,
 					  fz->fz_order,
 					  fa->fa_tos,
+					  &fa->fa_age,
 					  fa->fa_info,
 					  NLM_F_MULTI) < 0) {
 				cb->args[4] = i;
diff --git a/net/ipv4/fib_lookup.h b/net/ipv4/fib_lookup.h
index eef9eec..c9145b5 100644
--- a/net/ipv4/fib_lookup.h
+++ b/net/ipv4/fib_lookup.h
@@ -13,6 +13,7 @@ struct fib_alias {
 	u8			fa_type;
 	u8			fa_scope;
 	u8			fa_state;
+	time_t			fa_age;
 };
 
 #define FA_S_ACCESSED	0x01
@@ -27,7 +28,7 @@ extern struct fib_info *fib_create_info(
 extern int fib_nh_match(struct fib_config *cfg, struct fib_info *fi);
 extern int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
 			 u32 tb_id, u8 type, u8 scope, __be32 dst,
-			 int dst_len, u8 tos, struct fib_info *fi,
+			 int dst_len, u8 tos, time_t *age, struct fib_info *fi,
 			 unsigned int);
 extern void rtmsg_fib(int event, __be32 key, struct fib_alias *fa,
 		      int dst_len, u32 tb_id, struct nl_info *info,
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index c434119..1822d92 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -278,7 +278,8 @@ static inline size_t fib_nlmsg_size(stru
 			 + nla_total_size(4) /* RTA_TABLE */
 			 + nla_total_size(4) /* RTA_DST */
 			 + nla_total_size(4) /* RTA_PRIORITY */
-			 + nla_total_size(4); /* RTA_PREFSRC */
+			 + nla_total_size(4) /* RTA_PREFSRC */
+			 + nla_total_size(4); /*RTA_AGE*/
 
 	/* space for nested metrics */
 	payload += nla_total_size((RTAX_MAX * nla_total_size(4)));
@@ -313,7 +314,7 @@ void rtmsg_fib(int event, __be32 key, st
 
 	err = fib_dump_info(skb, info->pid, seq, event, tb_id,
 			    fa->fa_type, fa->fa_scope, key, dst_len,
-			    fa->fa_tos, fa->fa_info, nlm_flags);
+			    fa->fa_tos, &fa->fa_age, fa->fa_info, nlm_flags);
 	if (err < 0) {
 		/* -EMSGSIZE implies BUG in fib_nlmsg_size() */
 		WARN_ON(err == -EMSGSIZE);
@@ -940,11 +941,12 @@ __be32 __fib_res_prefsrc(struct fib_resu
 }
 
 int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
-		  u32 tb_id, u8 type, u8 scope, __be32 dst, int dst_len, u8 tos,
+		  u32 tb_id, u8 type, u8 scope, __be32 dst, int dst_len, u8 tos, time_t *age,
 		  struct fib_info *fi, unsigned int flags)
 {
 	struct nlmsghdr *nlh;
 	struct rtmsg *rtm;
+	struct timeval tv;
 
 	nlh = nlmsg_put(skb, pid, seq, event, sizeof(*rtm), flags);
 	if (nlh == NULL)
@@ -985,6 +987,14 @@ int fib_dump_info(struct sk_buff *skb, u
 			NLA_PUT_U32(skb, RTA_FLOW, fi->fib_nh[0].nh_tclassid);
 #endif
 	}
+
+	do_gettimeofday(&tv);
+	if (!*age) {
+		*age = timeval_to_sec(&tv);
+		NLA_PUT_U32(skb, RTA_AGE, *age);
+	} else {
+		NLA_PUT_U32(skb, RTA_AGE, timeval_to_sec(&tv) - *age);
+	}
 #ifdef CONFIG_IP_ROUTE_MULTIPATH
 	if (fi->fib_nhs > 1) {
 		struct rtnexthop *rtnh;
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 30e332a..be2d1d6 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -1884,6 +1884,7 @@ static int fn_trie_dump_fa(t_key key, in
 				  xkey,
 				  plen,
 				  fa->fa_tos,
+				  &fa->fa_age,
 				  fa->fa_info, 0) < 0) {
 			cb->args[4] = i;
 			return -1;
-- 
1.4.3.4


^ permalink raw reply related

* [PATCH 2/4] Add new timeval_to_sec function
From: Varun Chandramohan @ 2007-07-23  4:41 UTC (permalink / raw)
  To: netdev; +Cc: sri, dlstevens, varuncha

A new function for converting timeval to time_t is added in time.h. Its a common function used in different
places.

Signed-off-by: Varun Chandramohan <varunc@linux.vnet.ibm.com>
---
 include/linux/time.h |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/include/linux/time.h b/include/linux/time.h
index dda9be6..c81baa6 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -147,6 +147,17 @@ static inline s64 timeval_to_ns(const st
 }
 
 /**
+ * timeval_to_sec - Convert timeval to seconds
+ * @tv:         pointer to the timeval variable to be converted
+ *
+ * Returns the seconds representation of timeval parameter.
+ */
+static inline time_t timeval_to_sec(const struct timeval *tv)
+{
+	return (tv->tv_sec + (tv->tv_usec + 500000)/1000000);
+}
+
+/**
  * ns_to_timespec - Convert nanoseconds to timespec
  * @nsec:	the nanoseconds value to be converted
  *
-- 
1.4.3.4


^ permalink raw reply related

* [PATCH 1/4] New attribute RTA_AGE
From: Varun Chandramohan @ 2007-07-23  4:41 UTC (permalink / raw)
  To: netdev; +Cc: sri, dlstevens, varuncha

A new attribute RTA_AGE is added for the age value to be exported to userlevel using netlink

Signed-off-by: Varun Chandramohan <varunc@linux.vnet.ibm.com>
---
 include/linux/rtnetlink.h |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index 6127858..884f507 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -263,6 +263,7 @@ enum rtattr_type_t
 	RTA_SESSION,
 	RTA_MP_ALGO, /* no longer used */
 	RTA_TABLE,
+	RTA_AGE,
 	__RTA_MAX
 };
 
-- 
1.4.3.4


^ permalink raw reply related

* [PATCH 0/4] Age Entry For IPv4 & IPv6 Route Table
From: Varun Chandramohan @ 2007-07-23  4:39 UTC (permalink / raw)
  To: netdev; +Cc: sri, dlstevens, varuncha

Hi,

According to the RFC 4292 (IP Forwarding Table MIB) there is a need for an age entry for all the routes in therouting table. The entry in the RFC is inetCidrRouteAge and oid is inetCidrRouteAge.1.10.
Many snmp application require this age entry. So iam adding the age field in the routing table for ipv4 and ipv6 and providing the interface for this value netlink.

Signed-off-by: Varun Chandramohan <varunc@linux.vnet.ibm.com>
---


^ permalink raw reply

* Re: [PATCH 00/10] Implement batching skb API
From: Krishna Kumar2 @ 2007-07-23  4:23 UTC (permalink / raw)
  To: Evgeniy Polyakov
  Cc: davem, gaagaan, general, hadi, herbert, jagana, jeff, kaber,
	kumarkr, mcarlson, mchan, netdev, peter.p.waskiewicz.jr, rdreier,
	rick.jones2, Robert.Olsson, sri, tgraf, xma
In-Reply-To: <20070720125423.GB13468@2ka.mipt.ru>

Hi Evgeniy,

Evgeniy Polyakov <johnpol@2ka.mipt.ru> wrote on 07/20/2007 06:24:23 PM:

> Hi Krishna.
>
> On Fri, Jul 20, 2007 at 12:01:49PM +0530, Krishna Kumar
(krkumar2@in.ibm.com) wrote:
> > After fine-tuning qdisc and other changes, I modified IPoIB to use this
API,
> > and now get good gains. Summary for TCP & No Delay: 1 process improves
for
> > all cases from 1.4% to 49.5%; 4 process has almost identical
improvements
> > from -1.7% to 59.1%; 16 process case also improves in the range of
-1.2% to
> > 33.4%; while 64 process doesn't have much improvement (-3.3% to 12.4%).
UDP
> > was tested with 1 process netperf with small increase in BW but big
> > improvement in Service Demand. Netperf latency tests show small drop in
> > transaction rate (results in separate attachment).
>
> What about round-robin tcp time and latency test? In theory such batching
> mode should not change that timings, but practice can show new aspects.

The TCP RR results show a slight impact, however the service demand shows
good improvement. The results are (I did TCP RR - 1 process, 1,8,32,128,512
buffer sizes; and UDP RR - 1 process, 1 byte buffer size) :

        Results for TCR RR (1 process) ORG code:
Size        R-R                   CPU%            S.Demand
------------------------------------------------------------
1         521346.02               5.48            1346.145
8         129463.14               6.74            418.370
32        128899.73               7.51            467.106
128       127230.15               5.42            340.876
512       119605.68               6.48            435.650


        Results for TCR RR (1 process) NEW code (and change%):
Size        R-R                   CPU%            S.Demand
--------------------------------------------------------------------
1         516596.62 (-0.91%)      5.74            1423.819 (5.77%)
8         129184.46 (-.22%)       5.43            336.747 (-19.51%)
32        128238.35 (-.51%)       5.43            339.213 (-27.38%)
128       126545.79 (-.54%)       5.36            339.188 (-0.50%)
512       119297.49 (-.26%)       5.16            346.185 (-20.54%)


              Results for UDP RR 1 process ORG & NEW code:
Code   Size      R-R                CPU%      S.Demand
----------------------------------------------------------------------
ORG     1        539327.86          5.68      1348.985
NEW     1        540669.33 (0.25%)  6.05      1434.180 (6.32%)


> I will review code later this week (likely tomorrow) and if there will
> be some issues return back.

Thanks! I had just submitted Rev2 on Sunday, please let me know what you
find.

Regards,

- KK


^ permalink raw reply

* [ofa-general] Re: [PATCH 02/12 -Rev2] Changes to netdevice.h
From: Krishna Kumar2 @ 2007-07-23  2:57 UTC (permalink / raw)
  To: Patrick McHardy
  Cc: jagana, johnpol, herbert, gaagaan, Robert.Olsson, kumarkr,
	rdreier, peter.p.waskiewicz.jr, hadi, mcarlson, jeff, general,
	mchan, tgraf, netdev, davem, sri
In-Reply-To: <46A38EAB.6050300@trash.net>

Hi Patrick,

Patrick McHardy <kaber@trash.net> wrote on 07/22/2007 10:36:51 PM:

> Krishna Kumar wrote:
> > @@ -472,6 +474,9 @@ struct net_device
> >     void         *priv;   /* pointer to private data   */
> >     int         (*hard_start_xmit) (struct sk_buff *skb,
> >                        struct net_device *dev);
> > +   int         (*hard_start_xmit_batch) (struct net_device
> > +                       *dev);
> > +
>
>
> Os this function really needed? Can't you just call hard_start_xmit with
> a NULL skb and have the driver use dev->blist?

Probably not. I will see how to do it this way and get back to you.

> >     /* These may be needed for future network-power-down code. */
> >     unsigned long      trans_start;   /* Time (in jiffies) of last Tx
*/
> >
> > @@ -582,6 +587,8 @@ struct net_device
> >  #define   NETDEV_ALIGN      32
> >  #define   NETDEV_ALIGN_CONST   (NETDEV_ALIGN - 1)
> >
> > +#define BATCHING_ON(dev)   ((dev->features & NETIF_F_BATCH_ON) != 0)
> > +
> >  static inline void *netdev_priv(const struct net_device *dev)
> >  {
> >     return dev->priv;
> > @@ -832,6 +839,8 @@ extern int      dev_set_mac_address(struct n
> >                     struct sockaddr *);
> >  extern int      dev_hard_start_xmit(struct sk_buff *skb,
> >                     struct net_device *dev);
> > +extern int      dev_add_skb_to_blist(struct sk_buff *skb,
> > +                    struct net_device *dev);
>
>
> Again, function signatures should be introduced in the same patch
> that contains the function. Splitting by file doesn't make sense.

Right. I did it for some but missed this. Sorry, will redo.

thanks,

- KK

^ permalink raw reply

* [ofa-general] Re: [PATCH 06/12 -Rev2] rtnetlink changes.
From: Krishna Kumar2 @ 2007-07-23  2:54 UTC (permalink / raw)
  To: Patrick McHardy
  Cc: jagana, johnpol, herbert, gaagaan, Robert.Olsson, kumarkr,
	rdreier, peter.p.waskiewicz.jr, hadi, mcarlson, jeff, general,
	mchan, tgraf, netdev, davem, sri
In-Reply-To: <46A38F8D.6080109@trash.net>

Hi Patrick,

Patrick McHardy <kaber@trash.net> wrote on 07/22/2007 10:40:37 PM:

> Krishna Kumar wrote:
> > diff -ruNp org/include/linux/if_link.h rev2/include/linux/if_link.h
> > --- org/include/linux/if_link.h   2007-07-20 16:33:35.000000000 +0530
> > +++ rev2/include/linux/if_link.h   2007-07-20 16:35:08.000000000 +0530
> > @@ -78,6 +78,8 @@ enum
> >     IFLA_LINKMODE,
> >     IFLA_LINKINFO,
> >  #define IFLA_LINKINFO IFLA_LINKINFO
> > +   IFLA_TXBTHSKB,      /* Driver support for Batch'd skbs */
> > +#define IFLA_TXBTHSKB IFLA_TXBTHSKB
>
>
> Ughh what a name :) I prefer pronouncable names since they are
> much easier to remember and don't need comments explaining
> what they mean.
>
> But I actually think offering just an ethtool interface would
> be better, at least for now.

Great, I will remove /sys and rtnetlink and keep the Ethtool i/f.

Thanks,

- KK

^ permalink raw reply

* [ofa-general] Re: [PATCH 11/12 -Rev2] IPoIB xmit API addition
From: Krishna Kumar2 @ 2007-07-23  2:53 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: jagana, johnpol, herbert, gaagaan, Robert.Olsson, kumarkr,
	mcarlson, peter.p.waskiewicz.jr, hadi, kaber, jeff, general,
	mchan, tgraf, netdev, sri, davem, rdreier
In-Reply-To: <20070722094136.GD7800@mellanox.co.il>

Hi Micheal,

"Michael S. Tsirkin" <mst@dev.mellanox.co.il> wrote on 07/22/2007 03:11:36
PM:

> > +   /*
> > +    * Handle skbs completion from tx_tail to wr_id. It is possible to
> > +    * handle WC's from earlier post_sends (possible multiple) in this
> > +    * iteration as we move from tx_tail to wr_id, since if the last
> > +    * WR (which is the one which had a completion request) failed to
be
> > +    * sent for any of those earlier request(s), no completion
> > +    * notification is generated for successful WR's of those earlier
> > +    * request(s).
> > +    */
>
> AFAIK a signalled WR will always generate a completion.
> What am I missing?

Yes, signalled WR will generate a completion. I am trying to catch the case
where, say, I send 64 skbs and set signalling for only the last skb and the
others are set to NO signalling. Now if the driver found the last WR was
bad
for some reason, it will synchronously fail the send for that WR (which
happens to be the only one that is signalled). So after the 1 to 63 skbs
are
finished, there will be no completion called. That was my understanding of
how
this works, and coded it that way so that the next post will clean up the
previous one's completion.

> >
> > +         /*
> > +          * Better error handling can be done here, like free
> > +          * all untried skbs if err == -ENOMEM. However at this
> > +          * time, we re-try all the skbs, all of which will
> > +          * likely fail anyway (unless device finished sending
> > +          * some out in the meantime). This is not a regression
> > +          * since the earlier code is not doing this either.
> > +          */
>
> Are you retrying posting skbs? Why is this a good idea?
> AFAIK, earlier code did not retry posting WRs at all.

Not exactly. If I send 64 skbs to the device and the provider returned a
bad WR at skb # 50, then I will have to try skb# 51-64 again since the
provider has not attemped to send those out as it bails out at the first
failure. The provider ofcourse has already sent out skb# 1-49 before
returning failure at skb# 50. So it is not strictly retry, just xmit of
next skbs which is what the current code also does. I tested this part out
by simulating errors in mthca_post_send and verified that the next
iteration clears up the remaining skbs.

> The comment seems to imply that post send fails as a result of SQ
overflow -

Correct.

> do you see SQ overflow errors in your testing?

No.

> AFAIK, IPoIB should never overflow the SQ.

Correct. It should never happen unless IPoIB has a bug :) I guess the
comment
should be removed ?

Thanks,

- KK

^ permalink raw reply

* Re: [PATCH] [IrDA] KS959 USB IrDA dongle support
From: David Miller @ 2007-07-23  1:35 UTC (permalink / raw)
  To: samuel-jcdQHdrhKHMdnm+yROfE0A
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, a_villacis-5itmuRygkZmgSpxsJD1C4w,
	linux-usb-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	irda-users-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <20070722213217.GA5893-jcdQHdrhKHMdnm+yROfE0A@public.gmane.org>

From: Samuel Ortiz <samuel-jcdQHdrhKHMdnm+yROfE0A@public.gmane.org>
Date: Mon, 23 Jul 2007 00:32:17 +0300

> Last IrDA patch for 2.6.23-rc1, if it's not too late...

Too late, Linus just closed the merge window, you had two
weeks to submit this :-)

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/

^ permalink raw reply

* net/bluetooth/rfcomm/tty.c: use-after-free
From: Adrian Bunk @ 2007-07-23  1:25 UTC (permalink / raw)
  To: Ville Tervo, Marcel Holtmann, maxk; +Cc: bluez-devel, linux-kernel, netdev

Commit 8de0a15483b357d0f0b821330ec84d1660cadc4e added the following 
use-after-free in net/bluetooth/rfcomm/tty.c:

<--  snip  -->

...
static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
{
...
        if (IS_ERR(dev->tty_dev)) {
                list_del(&dev->list);
                kfree(dev);
                return PTR_ERR(dev->tty_dev);
        }
...

<--  snip  -->

Spotted by the Coverity checker.

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


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