netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: igorm@etf.rs
To: netdev@vger.kernel.org
Cc: davem@davemloft.net, Igor Maravic <igorm@etf.rs>
Subject: [PATCH 07/10 net-next] net:ipv4:devinet: Add support for alloc/free of per device stats and (un)register of per device proc files
Date: Fri, 16 Dec 2011 16:26:00 +0100	[thread overview]
Message-ID: <1324049163-11207-8-git-send-email-igorm@etf.rs> (raw)
In-Reply-To: <1324049163-11207-1-git-send-email-igorm@etf.rs>

From: Igor Maravic <igorm@etf.rs>

Added function snmp_alloc_dev and snmp_free_dev for
allocing/freeing per device statistics.

snmp_alloc_dev is only called when in_device is created. If it failes,
in_device can't be created.
snmp_free_dev is only called when in_device is destroyed.

Added calls for snmp_(un)register_dev functions.

snmp_unregister_dev is called when in_device is destroyed and when it changes name.
snmp_register_dev is called when in_device is created. If it failes in_device
can be created. snmp_register_dev is also called when in_device change name.

Signed-off-by: Igor Maravic <igorm@etf.rs>
---
 net/ipv4/devinet.c |   75 +++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 66 insertions(+), 9 deletions(-)

diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 65f01dc..c18564f 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -211,6 +211,38 @@ static inline void inet_free_ifa(struct in_ifaddr *ifa)
 	call_rcu(&ifa->rcu_head, inet_rcu_free_ifa);
 }
 
+static int snmp_alloc_dev(struct in_device *idev)
+{
+	if (snmp_mib_init((void __percpu **)idev->stats.ip,
+			sizeof(struct ipstats_mib),
+			__alignof__(struct ipstats_mib)) < 0)
+		goto err_ip;
+	idev->stats.icmpdev = kzalloc(sizeof(struct icmp_mib_dev),
+						GFP_KERNEL);
+	if (!idev->stats.icmpdev)
+		goto err_icmp;
+	idev->stats.icmpmsgdev = kzalloc(sizeof(struct icmpmsg_mib_dev),
+						GFP_KERNEL);
+	if (!idev->stats.icmpmsgdev)
+		goto err_icmpmsg;
+
+	return 0;
+
+err_icmpmsg:
+	kfree(idev->stats.icmpdev);
+err_icmp:
+	snmp_mib_free((void __percpu **)idev->stats.ip);
+err_ip:
+	return -ENOMEM;
+}
+
+static void snmp_free_dev(struct in_device *idev)
+{
+	kfree(idev->stats.icmpmsgdev);
+	kfree(idev->stats.icmpdev);
+	snmp_mib_free((void __percpu **)idev->stats.ip);
+}
+
 void in_dev_finish_destroy(struct in_device *idev)
 {
 	struct net_device *dev = idev->dev;
@@ -224,8 +256,10 @@ void in_dev_finish_destroy(struct in_device *idev)
 	dev_put(dev);
 	if (!idev->dead)
 		pr_err("Freeing alive in_device %p\n", idev);
-	else
+	else {
+		snmp_free_dev(idev);
 		kfree(idev);
+	}
 }
 EXPORT_SYMBOL(in_dev_finish_destroy);
 
@@ -249,6 +283,22 @@ static struct in_device *inetdev_init(struct net_device *dev)
 		dev_disable_lro(dev);
 	/* Reference in_dev->dev */
 	dev_hold(dev);
+
+	if (snmp_alloc_dev(in_dev) < 0) {
+		printk(KERN_CRIT
+			"%s(): cannot allocate memory for statistics; dev=%s.\n",
+			__func__, dev->name);
+		neigh_parms_release(&arp_tbl, in_dev->arp_parms);
+		dev_put(dev);
+		kfree(in_dev);
+		return NULL;
+	}
+
+	if (snmp_register_dev(in_dev) < 0)
+		printk(KERN_WARNING
+			"%s(): cannot create /proc/net/dev_snmp/%s\n",
+			__func__, dev->name);
+
 	/* Account for reference dev->ip_ptr (below) */
 	in_dev_hold(in_dev);
 
@@ -292,6 +342,7 @@ static void inetdev_destroy(struct in_device *in_dev)
 	}
 
 	RCU_INIT_POINTER(dev->ip_ptr, NULL);
+	snmp_unregister_dev(in_dev);
 
 	devinet_sysctl_unregister(in_dev);
 	neigh_parms_release(&arp_tbl, in_dev->arp_parms);
@@ -1222,14 +1273,20 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
 	case NETDEV_UNREGISTER:
 		inetdev_destroy(in_dev);
 		break;
-	case NETDEV_CHANGENAME:
-		/* Do not notify about label change, this event is
-		 * not interesting to applications using netlink.
-		 */
-		inetdev_changename(dev, in_dev);
-
-		devinet_sysctl_unregister(in_dev);
-		devinet_sysctl_register(in_dev);
+	case NETDEV_CHANGENAME: {
+			int err;
+			/* Do not notify about label change, this event is
+			 * not interesting to applications using netlink.
+			 */
+			inetdev_changename(dev, in_dev);
+
+			snmp_unregister_dev(in_dev);
+			devinet_sysctl_unregister(in_dev);
+			devinet_sysctl_register(in_dev);
+			err = snmp_register_dev(in_dev);
+			if (err)
+				return notifier_from_errno(err);
+		}
 		break;
 	}
 out:
-- 
1.7.5.4

  parent reply	other threads:[~2011-12-16 15:26 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-12-16 15:25 [PATCH 00/10 net-next] Introduce per interface ipv4 statistics igorm
2011-12-16 15:25 ` [PATCH 01/10 net-next] include: net: netns: mib: Add proc_dir_entry for ipv4 per interface stats igorm
2011-12-16 15:25 ` [PATCH 02/10 net-next] include: net: snmp: Create icmp per device counters and add macros for per device stats igorm
2011-12-16 15:25 ` [PATCH 03/10 net-next] include:linux:inetdevice: Add struct ipv4_devstat and func __in_dev_get_rcu_safely igorm
2011-12-16 15:25 ` [PATCH 04/10 net-next] include:net:ipv6: Moved _DEV* macros igorm
2011-12-16 15:25 ` [PATCH 05/10 net-next] include:net:ip: Tuned up IP_*_STATS macros for per device statistics and added functions for (un)registering per device proc entries igorm
2011-12-16 15:25 ` [PATCH 06/10 net-next] include:net:icmp: Tuned up ICMP_*_STATS macros for per device statistics and changed prototype for icmp_out_count igorm
2011-12-16 15:26 ` igorm [this message]
2011-12-16 15:26 ` [PATCH 08/10 net-next] net:ipv4:af_inet: Init proc fs before ip_init igorm
2011-12-16 15:26 ` [PATCH 09/10 net-next] net:ipv4:proc: Introduce proc files for ipv4 per interface stats igorm
2011-12-16 15:26 ` [PATCH 10/10 net-next] net: Enable ipv4 per interface statistics igorm
2011-12-16 15:41 ` [PATCH 00/10 net-next] Introduce per interface ipv4 statistics Eric Dumazet
2011-12-16 15:58   ` Igor Maravić
2011-12-16 16:33     ` Eric Dumazet
2011-12-16 16:44       ` Christoph Lameter
2011-12-16 16:50         ` Eric Dumazet
2011-12-16 16:55           ` Christoph Lameter
2011-12-16 17:14             ` Eric Dumazet
2011-12-16 17:29               ` Christoph Lameter
2011-12-16 18:08                 ` Eric Dumazet
2011-12-16 18:30                   ` Christoph Lameter
2011-12-16 18:39                 ` David Miller
2011-12-16 17:19             ` Stephen Hemminger
2011-12-16 18:31       ` David Miller
2011-12-16 18:28     ` David Miller
2011-12-16 18:27   ` David Miller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1324049163-11207-8-git-send-email-igorm@etf.rs \
    --to=igorm@etf.rs \
    --cc=davem@davemloft.net \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).