diff options
Diffstat (limited to 'net/core/net-sysfs.c')
| -rw-r--r-- | net/core/net-sysfs.c | 120 | 
1 files changed, 83 insertions, 37 deletions
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index d954b56b4e4..1cac29ebb05 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -104,6 +104,7 @@ static ssize_t netdev_store(struct device *dev, struct device_attribute *attr,  }  NETDEVICE_SHOW_RO(dev_id, fmt_hex); +NETDEVICE_SHOW_RO(dev_port, fmt_dec);  NETDEVICE_SHOW_RO(addr_assign_type, fmt_dec);  NETDEVICE_SHOW_RO(addr_len, fmt_dec);  NETDEVICE_SHOW_RO(iflink, fmt_dec); @@ -252,6 +253,16 @@ static ssize_t operstate_show(struct device *dev,  }  static DEVICE_ATTR_RO(operstate); +static ssize_t carrier_changes_show(struct device *dev, +				    struct device_attribute *attr, +				    char *buf) +{ +	struct net_device *netdev = to_net_dev(dev); +	return sprintf(buf, fmt_dec, +		       atomic_read(&netdev->carrier_changes)); +} +static DEVICE_ATTR_RO(carrier_changes); +  /* read-write attributes */  static int change_mtu(struct net_device *net, unsigned long new_mtu) @@ -373,6 +384,7 @@ static struct attribute *net_class_attrs[] = {  	&dev_attr_netdev_group.attr,  	&dev_attr_type.attr,  	&dev_attr_dev_id.attr, +	&dev_attr_dev_port.attr,  	&dev_attr_iflink.attr,  	&dev_attr_ifindex.attr,  	&dev_attr_addr_assign_type.attr, @@ -384,6 +396,7 @@ static struct attribute *net_class_attrs[] = {  	&dev_attr_duplex.attr,  	&dev_attr_dormant.attr,  	&dev_attr_operstate.attr, +	&dev_attr_carrier_changes.attr,  	&dev_attr_ifalias.attr,  	&dev_attr_carrier.attr,  	&dev_attr_mtu.attr, @@ -498,17 +511,7 @@ static struct attribute_group wireless_group = {  #define net_class_groups	NULL  #endif /* CONFIG_SYSFS */ -#ifdef CONFIG_RPS -/* - * RX queue sysfs structures and functions. - */ -struct rx_queue_attribute { -	struct attribute attr; -	ssize_t (*show)(struct netdev_rx_queue *queue, -	    struct rx_queue_attribute *attr, char *buf); -	ssize_t (*store)(struct netdev_rx_queue *queue, -	    struct rx_queue_attribute *attr, const char *buf, size_t len); -}; +#ifdef CONFIG_SYSFS  #define to_rx_queue_attr(_attr) container_of(_attr,		\      struct rx_queue_attribute, attr) @@ -543,6 +546,7 @@ static const struct sysfs_ops rx_queue_sysfs_ops = {  	.store = rx_queue_attr_store,  }; +#ifdef CONFIG_RPS  static ssize_t show_rps_map(struct netdev_rx_queue *queue,  			    struct rx_queue_attribute *attribute, char *buf)  { @@ -676,8 +680,8 @@ static ssize_t store_rps_dev_flow_table_cnt(struct netdev_rx_queue *queue,  		while ((mask | (mask >> 1)) != mask)  			mask |= (mask >> 1);  		/* On 64 bit arches, must check mask fits in table->mask (u32), -		 * and on 32bit arches, must check RPS_DEV_FLOW_TABLE_SIZE(mask + 1) -		 * doesnt overflow. +		 * and on 32bit arches, must check +		 * RPS_DEV_FLOW_TABLE_SIZE(mask + 1) doesn't overflow.  		 */  #if BITS_PER_LONG > 32  		if (mask > (unsigned long)(u32)mask) @@ -718,16 +722,20 @@ static struct rx_queue_attribute rps_cpus_attribute =  static struct rx_queue_attribute rps_dev_flow_table_cnt_attribute =  	__ATTR(rps_flow_cnt, S_IRUGO | S_IWUSR,  	    show_rps_dev_flow_table_cnt, store_rps_dev_flow_table_cnt); +#endif /* CONFIG_RPS */  static struct attribute *rx_queue_default_attrs[] = { +#ifdef CONFIG_RPS  	&rps_cpus_attribute.attr,  	&rps_dev_flow_table_cnt_attribute.attr, +#endif  	NULL  };  static void rx_queue_release(struct kobject *kobj)  {  	struct netdev_rx_queue *queue = to_rx_queue(kobj); +#ifdef CONFIG_RPS  	struct rps_map *map;  	struct rps_dev_flow_table *flow_table; @@ -743,15 +751,29 @@ static void rx_queue_release(struct kobject *kobj)  		RCU_INIT_POINTER(queue->rps_flow_table, NULL);  		call_rcu(&flow_table->rcu, rps_dev_flow_table_release);  	} +#endif  	memset(kobj, 0, sizeof(*kobj));  	dev_put(queue->dev);  } +static const void *rx_queue_namespace(struct kobject *kobj) +{ +	struct netdev_rx_queue *queue = to_rx_queue(kobj); +	struct device *dev = &queue->dev->dev; +	const void *ns = NULL; + +	if (dev->class && dev->class->ns_type) +		ns = dev->class->namespace(dev); + +	return ns; +} +  static struct kobj_type rx_queue_ktype = {  	.sysfs_ops = &rx_queue_sysfs_ops,  	.release = rx_queue_release,  	.default_attrs = rx_queue_default_attrs, +	.namespace = rx_queue_namespace  };  static int rx_queue_add_kobject(struct net_device *net, int index) @@ -763,25 +785,36 @@ static int rx_queue_add_kobject(struct net_device *net, int index)  	kobj->kset = net->queues_kset;  	error = kobject_init_and_add(kobj, &rx_queue_ktype, NULL,  	    "rx-%u", index); -	if (error) { -		kobject_put(kobj); -		return error; +	if (error) +		goto exit; + +	if (net->sysfs_rx_queue_group) { +		error = sysfs_create_group(kobj, net->sysfs_rx_queue_group); +		if (error) +			goto exit;  	}  	kobject_uevent(kobj, KOBJ_ADD);  	dev_hold(queue->dev);  	return error; +exit: +	kobject_put(kobj); +	return error;  } -#endif /* CONFIG_RPS */ +#endif /* CONFIG_SYSFS */  int  net_rx_queue_update_kobjects(struct net_device *net, int old_num, int new_num)  { -#ifdef CONFIG_RPS +#ifdef CONFIG_SYSFS  	int i;  	int error = 0; +#ifndef CONFIG_RPS +	if (!net->sysfs_rx_queue_group) +		return 0; +#endif  	for (i = old_num; i < new_num; i++) {  		error = rx_queue_add_kobject(net, i);  		if (error) { @@ -790,8 +823,12 @@ net_rx_queue_update_kobjects(struct net_device *net, int old_num, int new_num)  		}  	} -	while (--i >= new_num) +	while (--i >= new_num) { +		if (net->sysfs_rx_queue_group) +			sysfs_remove_group(&net->_rx[i].kobj, +					   net->sysfs_rx_queue_group);  		kobject_put(&net->_rx[i].kobj); +	}  	return error;  #else @@ -972,15 +1009,12 @@ static struct attribute_group dql_group = {  #endif /* CONFIG_BQL */  #ifdef CONFIG_XPS -static inline unsigned int get_netdev_queue_index(struct netdev_queue *queue) +static unsigned int get_netdev_queue_index(struct netdev_queue *queue)  {  	struct net_device *dev = queue->dev; -	int i; - -	for (i = 0; i < dev->num_tx_queues; i++) -		if (queue == &dev->_tx[i]) -			break; +	unsigned int i; +	i = queue - dev->_tx;  	BUG_ON(i >= dev->num_tx_queues);  	return i; @@ -1082,10 +1116,23 @@ static void netdev_queue_release(struct kobject *kobj)  	dev_put(queue->dev);  } +static const void *netdev_queue_namespace(struct kobject *kobj) +{ +	struct netdev_queue *queue = to_netdev_queue(kobj); +	struct device *dev = &queue->dev->dev; +	const void *ns = NULL; + +	if (dev->class && dev->class->ns_type) +		ns = dev->class->namespace(dev); + +	return ns; +} +  static struct kobj_type netdev_queue_ktype = {  	.sysfs_ops = &netdev_queue_sysfs_ops,  	.release = netdev_queue_release,  	.default_attrs = netdev_queue_default_attrs, +	.namespace = netdev_queue_namespace,  };  static int netdev_queue_add_kobject(struct net_device *net, int index) @@ -1155,9 +1202,6 @@ static int register_queue_kobjects(struct net_device *net)  	    NULL, &net->dev.kobj);  	if (!net->queues_kset)  		return -ENOMEM; -#endif - -#ifdef CONFIG_RPS  	real_rx = net->real_num_rx_queues;  #endif  	real_tx = net->real_num_tx_queues; @@ -1184,7 +1228,7 @@ static void remove_queue_kobjects(struct net_device *net)  {  	int real_rx = 0, real_tx = 0; -#ifdef CONFIG_RPS +#ifdef CONFIG_SYSFS  	real_rx = net->real_num_rx_queues;  #endif  	real_tx = net->real_num_tx_queues; @@ -1263,7 +1307,7 @@ static void netdev_release(struct device *d)  	BUG_ON(dev->reg_state != NETREG_RELEASED);  	kfree(dev->ifalias); -	kfree((char *)dev - dev->padded); +	netdev_freemem(dev);  }  static const void *net_namespace(struct device *d) @@ -1344,19 +1388,21 @@ int netdev_register_kobject(struct net_device *net)  	return error;  } -int netdev_class_create_file(struct class_attribute *class_attr) +int netdev_class_create_file_ns(struct class_attribute *class_attr, +				const void *ns)  { -	return class_create_file(&net_class, class_attr); +	return class_create_file_ns(&net_class, class_attr, ns);  } -EXPORT_SYMBOL(netdev_class_create_file); +EXPORT_SYMBOL(netdev_class_create_file_ns); -void netdev_class_remove_file(struct class_attribute *class_attr) +void netdev_class_remove_file_ns(struct class_attribute *class_attr, +				 const void *ns)  { -	class_remove_file(&net_class, class_attr); +	class_remove_file_ns(&net_class, class_attr, ns);  } -EXPORT_SYMBOL(netdev_class_remove_file); +EXPORT_SYMBOL(netdev_class_remove_file_ns); -int netdev_kobject_init(void) +int __init netdev_kobject_init(void)  {  	kobj_ns_type_register(&net_ns_type_operations);  	return class_register(&net_class);  | 
