All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sudeep Holla <sudeep.holla@arm.com>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Sudeep Holla <sudeep.holla@arm.com>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	Heiko Carstens <heiko.carstens@de.ibm.com>,
	Lorenzo Pieralisi <Lorenzo.Pieralisi@arm.com>,
	Rob Herring <robh@kernel.org>,
	"linux-doc@vger.kernel.org" <linux-doc@vger.kernel.org>,
	"linux-ia64@vger.kernel.org" <linux-ia64@vger.kernel.org>,
	"linux390@de.ibm.com" <linux390@de.ibm.com>,
	"linux-s390@vger.kernel.org" <linux-s390@vger.kernel.org>,
	"x86@kernel.org" <x86@kernel.org>,
	"linuxppc-dev@lists.ozlabs.org" <linuxppc-dev@lists.ozlabs.org>,
	"linux-arm-kernel@lists.infradead.org" 
	<linux-arm-kernel@lists.infradead.org>
Subject: Re: [PATCH 2/9] drivers: base: support cpu cache information interface to userspace via sysfs
Date: Thu, 10 Jul 2014 14:37:23 +0100	[thread overview]
Message-ID: <53BE9713.8090700@arm.com> (raw)
In-Reply-To: <20140710000905.GA18025@kroah.com>

Hi Greg,

Thanks for reviewing this.

On 10/07/14 01:09, Greg Kroah-Hartman wrote:
> On Wed, Jun 25, 2014 at 06:30:37PM +0100, Sudeep Holla wrote:
>> +static const struct device_attribute *cache_optional_attrs[] = {
>> +	&dev_attr_coherency_line_size,
>> +	&dev_attr_ways_of_associativity,
>> +	&dev_attr_number_of_sets,
>> +	&dev_attr_size,
>> +	&dev_attr_attributes,
>> +	&dev_attr_physical_line_partition,
>> +	NULL
>> +};
>> +
>> +static int device_add_attrs(struct device *dev,
>> +			    const struct device_attribute **dev_attrs)
>> +{
>> +	int i, error = 0;
>> +	struct device_attribute *dev_attr;
>> +	char *buf;
>> +
>> +	if (!dev_attrs)
>> +		return 0;
>> +
>> +	buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
>> +	if (!buf)
>> +		return -ENOMEM;
>> +
>> +	for (i = 0; dev_attrs[i]; i++) {
>> +		dev_attr = (struct device_attribute *)dev_attrs[i];
>> +
>> +		/* create attributes that provides meaningful value */
>> +		if (dev_attr->show(dev, dev_attr, buf) < 0)
>> +			continue;
>> +
>> +		error = device_create_file(dev, dev_attrs[i]);
>> +		if (error) {
>> +			while (--i >= 0)
>> +				device_remove_file(dev, dev_attrs[i]);
>> +			break;
>> +		}
>> +	}
>> +
>> +	kfree(buf);
>> +	return error;
>> +}
>
> Ick, why create your own function for this when the driver core has this
> functionality built into it?  Look at the is_visible() callback, and how
> it is use for an attribute group please.
>

I agree even I added this function hesitantly as didn't realize that I can use
is_visible for this purpose. Thanks for pointing that out I will have a look
at it.

>> +static void device_remove_attrs(struct device *dev,
>> +				const struct device_attribute **dev_attrs)
>> +{
>> +	int i;
>> +
>> +	if (!dev_attrs)
>> +		return;
>> +
>> +	for (i = 0; dev_attrs[i]; dev_attrs++, i++)
>> +		device_remove_file(dev, dev_attrs[i]);
>> +}
>
> You should just remove a whole group at once, not individually.
>

Right, I must be able to get rid of these 2 functions once I use
is_visible callback.

>> +
>> +const struct device_attribute **
>> +__weak cache_get_priv_attr(struct device *cache_idx_dev)
>> +{
>> +	return NULL;
>> +}
>> +
>> +/* Add/Remove cache interface for CPU device */
>> +static void cpu_cache_sysfs_exit(unsigned int cpu)
>> +{
>> +	int i;
>> +	struct device *tmp_dev;
>> +	const struct device_attribute **ci_priv_attr;
>> +
>> +	if (per_cpu_index_dev(cpu)) {
>> +		for (i = 0; i < cache_leaves(cpu); i++) {
>> +			tmp_dev = per_cache_index_dev(cpu, i);
>> +			if (!tmp_dev)
>> +				continue;
>> +			ci_priv_attr = cache_get_priv_attr(tmp_dev);
>> +			device_remove_attrs(tmp_dev, ci_priv_attr);
>> +			device_remove_attrs(tmp_dev, cache_optional_attrs);
>> +			device_unregister(tmp_dev);
>> +		}
>> +		kfree(per_cpu_index_dev(cpu));
>> +		per_cpu_index_dev(cpu) = NULL;
>> +	}
>> +	device_unregister(per_cpu_cache_dev(cpu));
>> +	per_cpu_cache_dev(cpu) = NULL;
>> +}
>> +
>> +static int cpu_cache_sysfs_init(unsigned int cpu)
>> +{
>> +	struct device *dev = get_cpu_device(cpu);
>> +
>> +	if (per_cpu_cacheinfo(cpu) == NULL)
>> +		return -ENOENT;
>> +
>> +	per_cpu_cache_dev(cpu) = device_create(dev->class, dev, cpu,
>> +					       NULL, "cache");
>> +	if (IS_ERR_OR_NULL(per_cpu_cache_dev(cpu)))
>> +		return PTR_ERR(per_cpu_cache_dev(cpu));
>> +
>> +	/* Allocate all required memory */
>> +	per_cpu_index_dev(cpu) = kzalloc(sizeof(struct device *) *
>> +					 cache_leaves(cpu), GFP_KERNEL);
>> +	if (unlikely(per_cpu_index_dev(cpu) == NULL))
>> +		goto err_out;
>> +
>> +	return 0;
>> +
>> +err_out:
>> +	cpu_cache_sysfs_exit(cpu);
>> +	return -ENOMEM;
>> +}
>> +
>> +static int cache_add_dev(unsigned int cpu)
>> +{
>> +	unsigned short i;
>> +	int rc;
>> +	struct device *tmp_dev, *parent;
>> +	struct cacheinfo *this_leaf;
>> +	const struct device_attribute **ci_priv_attr;
>> +	struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
>> +
>> +	rc = cpu_cache_sysfs_init(cpu);
>> +	if (unlikely(rc < 0))
>> +		return rc;
>> +
>> +	parent = per_cpu_cache_dev(cpu);
>> +	for (i = 0; i < cache_leaves(cpu); i++) {
>> +		this_leaf = this_cpu_ci->info_list + i;
>> +		if (this_leaf->disable_sysfs)
>> +			continue;
>> +		tmp_dev = device_create_with_groups(parent->class, parent, i,
>> +						    this_leaf,
>> +						    cache_default_groups,
>> +						    "index%1u", i);
>> +		if (IS_ERR_OR_NULL(tmp_dev)) {
>> +			rc = PTR_ERR(tmp_dev);
>> +			goto err;
>> +		}
>> +
>> +		rc = device_add_attrs(tmp_dev, cache_optional_attrs);
>> +		if (unlikely(rc))
>> +			goto err;
>> +
>> +		ci_priv_attr = cache_get_priv_attr(tmp_dev);
>> +		rc = device_add_attrs(tmp_dev, ci_priv_attr);
>> +		if (unlikely(rc))
>> +			goto err;
>
> You just raced with userspace here, creating these files _after_ the
> device was announced to userspace, causing problems with anyone wanting
> to read these attributes :(
>
> I think if you fix up the is_visible() thing above, these calls will go
> away, right?
>

Yes I agree.

Regards,
Sudeep


WARNING: multiple messages have this Message-ID (diff)
From: Sudeep Holla <sudeep.holla@arm.com>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Rob Herring <robh@kernel.org>,
	Lorenzo Pieralisi <Lorenzo.Pieralisi@arm.com>,
	"linux-ia64@vger.kernel.org" <linux-ia64@vger.kernel.org>,
	"linux-doc@vger.kernel.org" <linux-doc@vger.kernel.org>,
	"linux-s390@vger.kernel.org" <linux-s390@vger.kernel.org>,
	"x86@kernel.org" <x86@kernel.org>,
	Heiko Carstens <heiko.carstens@de.ibm.com>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	Sudeep Holla <sudeep.holla@arm.com>,
	"linux390@de.ibm.com" <linux390@de.ibm.com>,
	"linuxppc-dev@lists.ozlabs.org" <linuxppc-dev@lists.ozlabs.org>,
	"linux-arm-kernel@lists.infradead.org"
	<linux-arm-kernel@lists.infradead.org>
Subject: Re: [PATCH 2/9] drivers: base: support cpu cache information interface to userspace via sysfs
Date: Thu, 10 Jul 2014 14:37:23 +0100	[thread overview]
Message-ID: <53BE9713.8090700@arm.com> (raw)
In-Reply-To: <20140710000905.GA18025@kroah.com>

Hi Greg,

Thanks for reviewing this.

On 10/07/14 01:09, Greg Kroah-Hartman wrote:
> On Wed, Jun 25, 2014 at 06:30:37PM +0100, Sudeep Holla wrote:
>> +static const struct device_attribute *cache_optional_attrs[] =3D {
>> +=09&dev_attr_coherency_line_size,
>> +=09&dev_attr_ways_of_associativity,
>> +=09&dev_attr_number_of_sets,
>> +=09&dev_attr_size,
>> +=09&dev_attr_attributes,
>> +=09&dev_attr_physical_line_partition,
>> +=09NULL
>> +};
>> +
>> +static int device_add_attrs(struct device *dev,
>> +=09=09=09    const struct device_attribute **dev_attrs)
>> +{
>> +=09int i, error =3D 0;
>> +=09struct device_attribute *dev_attr;
>> +=09char *buf;
>> +
>> +=09if (!dev_attrs)
>> +=09=09return 0;
>> +
>> +=09buf =3D kmalloc(PAGE_SIZE, GFP_KERNEL);
>> +=09if (!buf)
>> +=09=09return -ENOMEM;
>> +
>> +=09for (i =3D 0; dev_attrs[i]; i++) {
>> +=09=09dev_attr =3D (struct device_attribute *)dev_attrs[i];
>> +
>> +=09=09/* create attributes that provides meaningful value */
>> +=09=09if (dev_attr->show(dev, dev_attr, buf) < 0)
>> +=09=09=09continue;
>> +
>> +=09=09error =3D device_create_file(dev, dev_attrs[i]);
>> +=09=09if (error) {
>> +=09=09=09while (--i >=3D 0)
>> +=09=09=09=09device_remove_file(dev, dev_attrs[i]);
>> +=09=09=09break;
>> +=09=09}
>> +=09}
>> +
>> +=09kfree(buf);
>> +=09return error;
>> +}
>
> Ick, why create your own function for this when the driver core has this
> functionality built into it?  Look at the is_visible() callback, and how
> it is use for an attribute group please.
>

I agree even I added this function hesitantly as didn't realize that I can =
use
is_visible for this purpose. Thanks for pointing that out I will have a loo=
k
at it.

>> +static void device_remove_attrs(struct device *dev,
>> +=09=09=09=09const struct device_attribute **dev_attrs)
>> +{
>> +=09int i;
>> +
>> +=09if (!dev_attrs)
>> +=09=09return;
>> +
>> +=09for (i =3D 0; dev_attrs[i]; dev_attrs++, i++)
>> +=09=09device_remove_file(dev, dev_attrs[i]);
>> +}
>
> You should just remove a whole group at once, not individually.
>

Right, I must be able to get rid of these 2 functions once I use
is_visible callback.

>> +
>> +const struct device_attribute **
>> +__weak cache_get_priv_attr(struct device *cache_idx_dev)
>> +{
>> +=09return NULL;
>> +}
>> +
>> +/* Add/Remove cache interface for CPU device */
>> +static void cpu_cache_sysfs_exit(unsigned int cpu)
>> +{
>> +=09int i;
>> +=09struct device *tmp_dev;
>> +=09const struct device_attribute **ci_priv_attr;
>> +
>> +=09if (per_cpu_index_dev(cpu)) {
>> +=09=09for (i =3D 0; i < cache_leaves(cpu); i++) {
>> +=09=09=09tmp_dev =3D per_cache_index_dev(cpu, i);
>> +=09=09=09if (!tmp_dev)
>> +=09=09=09=09continue;
>> +=09=09=09ci_priv_attr =3D cache_get_priv_attr(tmp_dev);
>> +=09=09=09device_remove_attrs(tmp_dev, ci_priv_attr);
>> +=09=09=09device_remove_attrs(tmp_dev, cache_optional_attrs);
>> +=09=09=09device_unregister(tmp_dev);
>> +=09=09}
>> +=09=09kfree(per_cpu_index_dev(cpu));
>> +=09=09per_cpu_index_dev(cpu) =3D NULL;
>> +=09}
>> +=09device_unregister(per_cpu_cache_dev(cpu));
>> +=09per_cpu_cache_dev(cpu) =3D NULL;
>> +}
>> +
>> +static int cpu_cache_sysfs_init(unsigned int cpu)
>> +{
>> +=09struct device *dev =3D get_cpu_device(cpu);
>> +
>> +=09if (per_cpu_cacheinfo(cpu) =3D=3D NULL)
>> +=09=09return -ENOENT;
>> +
>> +=09per_cpu_cache_dev(cpu) =3D device_create(dev->class, dev, cpu,
>> +=09=09=09=09=09       NULL, "cache");
>> +=09if (IS_ERR_OR_NULL(per_cpu_cache_dev(cpu)))
>> +=09=09return PTR_ERR(per_cpu_cache_dev(cpu));
>> +
>> +=09/* Allocate all required memory */
>> +=09per_cpu_index_dev(cpu) =3D kzalloc(sizeof(struct device *) *
>> +=09=09=09=09=09 cache_leaves(cpu), GFP_KERNEL);
>> +=09if (unlikely(per_cpu_index_dev(cpu) =3D=3D NULL))
>> +=09=09goto err_out;
>> +
>> +=09return 0;
>> +
>> +err_out:
>> +=09cpu_cache_sysfs_exit(cpu);
>> +=09return -ENOMEM;
>> +}
>> +
>> +static int cache_add_dev(unsigned int cpu)
>> +{
>> +=09unsigned short i;
>> +=09int rc;
>> +=09struct device *tmp_dev, *parent;
>> +=09struct cacheinfo *this_leaf;
>> +=09const struct device_attribute **ci_priv_attr;
>> +=09struct cpu_cacheinfo *this_cpu_ci =3D get_cpu_cacheinfo(cpu);
>> +
>> +=09rc =3D cpu_cache_sysfs_init(cpu);
>> +=09if (unlikely(rc < 0))
>> +=09=09return rc;
>> +
>> +=09parent =3D per_cpu_cache_dev(cpu);
>> +=09for (i =3D 0; i < cache_leaves(cpu); i++) {
>> +=09=09this_leaf =3D this_cpu_ci->info_list + i;
>> +=09=09if (this_leaf->disable_sysfs)
>> +=09=09=09continue;
>> +=09=09tmp_dev =3D device_create_with_groups(parent->class, parent, i,
>> +=09=09=09=09=09=09    this_leaf,
>> +=09=09=09=09=09=09    cache_default_groups,
>> +=09=09=09=09=09=09    "index%1u", i);
>> +=09=09if (IS_ERR_OR_NULL(tmp_dev)) {
>> +=09=09=09rc =3D PTR_ERR(tmp_dev);
>> +=09=09=09goto err;
>> +=09=09}
>> +
>> +=09=09rc =3D device_add_attrs(tmp_dev, cache_optional_attrs);
>> +=09=09if (unlikely(rc))
>> +=09=09=09goto err;
>> +
>> +=09=09ci_priv_attr =3D cache_get_priv_attr(tmp_dev);
>> +=09=09rc =3D device_add_attrs(tmp_dev, ci_priv_attr);
>> +=09=09if (unlikely(rc))
>> +=09=09=09goto err;
>
> You just raced with userspace here, creating these files _after_ the
> device was announced to userspace, causing problems with anyone wanting
> to read these attributes :(
>
> I think if you fix up the is_visible() thing above, these calls will go
> away, right?
>

Yes I agree.

Regards,
Sudeep

WARNING: multiple messages have this Message-ID (diff)
From: sudeep.holla@arm.com (Sudeep Holla)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 2/9] drivers: base: support cpu cache information interface to userspace via sysfs
Date: Thu, 10 Jul 2014 14:37:23 +0100	[thread overview]
Message-ID: <53BE9713.8090700@arm.com> (raw)
In-Reply-To: <20140710000905.GA18025@kroah.com>

Hi Greg,

Thanks for reviewing this.

On 10/07/14 01:09, Greg Kroah-Hartman wrote:
> On Wed, Jun 25, 2014 at 06:30:37PM +0100, Sudeep Holla wrote:
>> +static const struct device_attribute *cache_optional_attrs[] = {
>> +	&dev_attr_coherency_line_size,
>> +	&dev_attr_ways_of_associativity,
>> +	&dev_attr_number_of_sets,
>> +	&dev_attr_size,
>> +	&dev_attr_attributes,
>> +	&dev_attr_physical_line_partition,
>> +	NULL
>> +};
>> +
>> +static int device_add_attrs(struct device *dev,
>> +			    const struct device_attribute **dev_attrs)
>> +{
>> +	int i, error = 0;
>> +	struct device_attribute *dev_attr;
>> +	char *buf;
>> +
>> +	if (!dev_attrs)
>> +		return 0;
>> +
>> +	buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
>> +	if (!buf)
>> +		return -ENOMEM;
>> +
>> +	for (i = 0; dev_attrs[i]; i++) {
>> +		dev_attr = (struct device_attribute *)dev_attrs[i];
>> +
>> +		/* create attributes that provides meaningful value */
>> +		if (dev_attr->show(dev, dev_attr, buf) < 0)
>> +			continue;
>> +
>> +		error = device_create_file(dev, dev_attrs[i]);
>> +		if (error) {
>> +			while (--i >= 0)
>> +				device_remove_file(dev, dev_attrs[i]);
>> +			break;
>> +		}
>> +	}
>> +
>> +	kfree(buf);
>> +	return error;
>> +}
>
> Ick, why create your own function for this when the driver core has this
> functionality built into it?  Look at the is_visible() callback, and how
> it is use for an attribute group please.
>

I agree even I added this function hesitantly as didn't realize that I can use
is_visible for this purpose. Thanks for pointing that out I will have a look
at it.

>> +static void device_remove_attrs(struct device *dev,
>> +				const struct device_attribute **dev_attrs)
>> +{
>> +	int i;
>> +
>> +	if (!dev_attrs)
>> +		return;
>> +
>> +	for (i = 0; dev_attrs[i]; dev_attrs++, i++)
>> +		device_remove_file(dev, dev_attrs[i]);
>> +}
>
> You should just remove a whole group at once, not individually.
>

Right, I must be able to get rid of these 2 functions once I use
is_visible callback.

>> +
>> +const struct device_attribute **
>> +__weak cache_get_priv_attr(struct device *cache_idx_dev)
>> +{
>> +	return NULL;
>> +}
>> +
>> +/* Add/Remove cache interface for CPU device */
>> +static void cpu_cache_sysfs_exit(unsigned int cpu)
>> +{
>> +	int i;
>> +	struct device *tmp_dev;
>> +	const struct device_attribute **ci_priv_attr;
>> +
>> +	if (per_cpu_index_dev(cpu)) {
>> +		for (i = 0; i < cache_leaves(cpu); i++) {
>> +			tmp_dev = per_cache_index_dev(cpu, i);
>> +			if (!tmp_dev)
>> +				continue;
>> +			ci_priv_attr = cache_get_priv_attr(tmp_dev);
>> +			device_remove_attrs(tmp_dev, ci_priv_attr);
>> +			device_remove_attrs(tmp_dev, cache_optional_attrs);
>> +			device_unregister(tmp_dev);
>> +		}
>> +		kfree(per_cpu_index_dev(cpu));
>> +		per_cpu_index_dev(cpu) = NULL;
>> +	}
>> +	device_unregister(per_cpu_cache_dev(cpu));
>> +	per_cpu_cache_dev(cpu) = NULL;
>> +}
>> +
>> +static int cpu_cache_sysfs_init(unsigned int cpu)
>> +{
>> +	struct device *dev = get_cpu_device(cpu);
>> +
>> +	if (per_cpu_cacheinfo(cpu) == NULL)
>> +		return -ENOENT;
>> +
>> +	per_cpu_cache_dev(cpu) = device_create(dev->class, dev, cpu,
>> +					       NULL, "cache");
>> +	if (IS_ERR_OR_NULL(per_cpu_cache_dev(cpu)))
>> +		return PTR_ERR(per_cpu_cache_dev(cpu));
>> +
>> +	/* Allocate all required memory */
>> +	per_cpu_index_dev(cpu) = kzalloc(sizeof(struct device *) *
>> +					 cache_leaves(cpu), GFP_KERNEL);
>> +	if (unlikely(per_cpu_index_dev(cpu) == NULL))
>> +		goto err_out;
>> +
>> +	return 0;
>> +
>> +err_out:
>> +	cpu_cache_sysfs_exit(cpu);
>> +	return -ENOMEM;
>> +}
>> +
>> +static int cache_add_dev(unsigned int cpu)
>> +{
>> +	unsigned short i;
>> +	int rc;
>> +	struct device *tmp_dev, *parent;
>> +	struct cacheinfo *this_leaf;
>> +	const struct device_attribute **ci_priv_attr;
>> +	struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
>> +
>> +	rc = cpu_cache_sysfs_init(cpu);
>> +	if (unlikely(rc < 0))
>> +		return rc;
>> +
>> +	parent = per_cpu_cache_dev(cpu);
>> +	for (i = 0; i < cache_leaves(cpu); i++) {
>> +		this_leaf = this_cpu_ci->info_list + i;
>> +		if (this_leaf->disable_sysfs)
>> +			continue;
>> +		tmp_dev = device_create_with_groups(parent->class, parent, i,
>> +						    this_leaf,
>> +						    cache_default_groups,
>> +						    "index%1u", i);
>> +		if (IS_ERR_OR_NULL(tmp_dev)) {
>> +			rc = PTR_ERR(tmp_dev);
>> +			goto err;
>> +		}
>> +
>> +		rc = device_add_attrs(tmp_dev, cache_optional_attrs);
>> +		if (unlikely(rc))
>> +			goto err;
>> +
>> +		ci_priv_attr = cache_get_priv_attr(tmp_dev);
>> +		rc = device_add_attrs(tmp_dev, ci_priv_attr);
>> +		if (unlikely(rc))
>> +			goto err;
>
> You just raced with userspace here, creating these files _after_ the
> device was announced to userspace, causing problems with anyone wanting
> to read these attributes :(
>
> I think if you fix up the is_visible() thing above, these calls will go
> away, right?
>

Yes I agree.

Regards,
Sudeep

WARNING: multiple messages have this Message-ID (diff)
From: Sudeep Holla <sudeep.holla@arm.com>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Sudeep Holla <sudeep.holla@arm.com>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	Heiko Carstens <heiko.carstens@de.ibm.com>,
	Lorenzo Pieralisi <Lorenzo.Pieralisi@arm.com>,
	Rob Herring <robh@kernel.org>,
	"linux-doc@vger.kernel.org" <linux-doc@vger.kernel.org>,
	"linux-ia64@vger.kernel.org" <linux-ia64@vger.kernel.org>,
	"linux390@de.ibm.com" <linux390@de.ibm.com>,
	"linux-s390@vger.kernel.org" <linux-s390@vger.kernel.org>,
	"x86@kernel.org" <x86@kernel.org>,
	"linuxppc-dev@lists.ozlabs.org" <linuxppc-dev@lists.ozlabs.org>,
	"linux-arm-kernel@lists.infradead.org"
	<linux-arm-kernel@lists.infradead.org>
Subject: Re: [PATCH 2/9] drivers: base: support cpu cache information interface to userspace via sysfs
Date: Thu, 10 Jul 2014 13:37:23 +0000	[thread overview]
Message-ID: <53BE9713.8090700@arm.com> (raw)
In-Reply-To: <20140710000905.GA18025@kroah.com>

Hi Greg,

Thanks for reviewing this.

On 10/07/14 01:09, Greg Kroah-Hartman wrote:
> On Wed, Jun 25, 2014 at 06:30:37PM +0100, Sudeep Holla wrote:
>> +static const struct device_attribute *cache_optional_attrs[] = {
>> +	&dev_attr_coherency_line_size,
>> +	&dev_attr_ways_of_associativity,
>> +	&dev_attr_number_of_sets,
>> +	&dev_attr_size,
>> +	&dev_attr_attributes,
>> +	&dev_attr_physical_line_partition,
>> +	NULL
>> +};
>> +
>> +static int device_add_attrs(struct device *dev,
>> +			    const struct device_attribute **dev_attrs)
>> +{
>> +	int i, error = 0;
>> +	struct device_attribute *dev_attr;
>> +	char *buf;
>> +
>> +	if (!dev_attrs)
>> +		return 0;
>> +
>> +	buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
>> +	if (!buf)
>> +		return -ENOMEM;
>> +
>> +	for (i = 0; dev_attrs[i]; i++) {
>> +		dev_attr = (struct device_attribute *)dev_attrs[i];
>> +
>> +		/* create attributes that provides meaningful value */
>> +		if (dev_attr->show(dev, dev_attr, buf) < 0)
>> +			continue;
>> +
>> +		error = device_create_file(dev, dev_attrs[i]);
>> +		if (error) {
>> +			while (--i >= 0)
>> +				device_remove_file(dev, dev_attrs[i]);
>> +			break;
>> +		}
>> +	}
>> +
>> +	kfree(buf);
>> +	return error;
>> +}
>
> Ick, why create your own function for this when the driver core has this
> functionality built into it?  Look at the is_visible() callback, and how
> it is use for an attribute group please.
>

I agree even I added this function hesitantly as didn't realize that I can use
is_visible for this purpose. Thanks for pointing that out I will have a look
at it.

>> +static void device_remove_attrs(struct device *dev,
>> +				const struct device_attribute **dev_attrs)
>> +{
>> +	int i;
>> +
>> +	if (!dev_attrs)
>> +		return;
>> +
>> +	for (i = 0; dev_attrs[i]; dev_attrs++, i++)
>> +		device_remove_file(dev, dev_attrs[i]);
>> +}
>
> You should just remove a whole group at once, not individually.
>

Right, I must be able to get rid of these 2 functions once I use
is_visible callback.

>> +
>> +const struct device_attribute **
>> +__weak cache_get_priv_attr(struct device *cache_idx_dev)
>> +{
>> +	return NULL;
>> +}
>> +
>> +/* Add/Remove cache interface for CPU device */
>> +static void cpu_cache_sysfs_exit(unsigned int cpu)
>> +{
>> +	int i;
>> +	struct device *tmp_dev;
>> +	const struct device_attribute **ci_priv_attr;
>> +
>> +	if (per_cpu_index_dev(cpu)) {
>> +		for (i = 0; i < cache_leaves(cpu); i++) {
>> +			tmp_dev = per_cache_index_dev(cpu, i);
>> +			if (!tmp_dev)
>> +				continue;
>> +			ci_priv_attr = cache_get_priv_attr(tmp_dev);
>> +			device_remove_attrs(tmp_dev, ci_priv_attr);
>> +			device_remove_attrs(tmp_dev, cache_optional_attrs);
>> +			device_unregister(tmp_dev);
>> +		}
>> +		kfree(per_cpu_index_dev(cpu));
>> +		per_cpu_index_dev(cpu) = NULL;
>> +	}
>> +	device_unregister(per_cpu_cache_dev(cpu));
>> +	per_cpu_cache_dev(cpu) = NULL;
>> +}
>> +
>> +static int cpu_cache_sysfs_init(unsigned int cpu)
>> +{
>> +	struct device *dev = get_cpu_device(cpu);
>> +
>> +	if (per_cpu_cacheinfo(cpu) = NULL)
>> +		return -ENOENT;
>> +
>> +	per_cpu_cache_dev(cpu) = device_create(dev->class, dev, cpu,
>> +					       NULL, "cache");
>> +	if (IS_ERR_OR_NULL(per_cpu_cache_dev(cpu)))
>> +		return PTR_ERR(per_cpu_cache_dev(cpu));
>> +
>> +	/* Allocate all required memory */
>> +	per_cpu_index_dev(cpu) = kzalloc(sizeof(struct device *) *
>> +					 cache_leaves(cpu), GFP_KERNEL);
>> +	if (unlikely(per_cpu_index_dev(cpu) = NULL))
>> +		goto err_out;
>> +
>> +	return 0;
>> +
>> +err_out:
>> +	cpu_cache_sysfs_exit(cpu);
>> +	return -ENOMEM;
>> +}
>> +
>> +static int cache_add_dev(unsigned int cpu)
>> +{
>> +	unsigned short i;
>> +	int rc;
>> +	struct device *tmp_dev, *parent;
>> +	struct cacheinfo *this_leaf;
>> +	const struct device_attribute **ci_priv_attr;
>> +	struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
>> +
>> +	rc = cpu_cache_sysfs_init(cpu);
>> +	if (unlikely(rc < 0))
>> +		return rc;
>> +
>> +	parent = per_cpu_cache_dev(cpu);
>> +	for (i = 0; i < cache_leaves(cpu); i++) {
>> +		this_leaf = this_cpu_ci->info_list + i;
>> +		if (this_leaf->disable_sysfs)
>> +			continue;
>> +		tmp_dev = device_create_with_groups(parent->class, parent, i,
>> +						    this_leaf,
>> +						    cache_default_groups,
>> +						    "index%1u", i);
>> +		if (IS_ERR_OR_NULL(tmp_dev)) {
>> +			rc = PTR_ERR(tmp_dev);
>> +			goto err;
>> +		}
>> +
>> +		rc = device_add_attrs(tmp_dev, cache_optional_attrs);
>> +		if (unlikely(rc))
>> +			goto err;
>> +
>> +		ci_priv_attr = cache_get_priv_attr(tmp_dev);
>> +		rc = device_add_attrs(tmp_dev, ci_priv_attr);
>> +		if (unlikely(rc))
>> +			goto err;
>
> You just raced with userspace here, creating these files _after_ the
> device was announced to userspace, causing problems with anyone wanting
> to read these attributes :(
>
> I think if you fix up the is_visible() thing above, these calls will go
> away, right?
>

Yes I agree.

Regards,
Sudeep


  reply	other threads:[~2014-07-10 13:36 UTC|newest]

Thread overview: 130+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-06-25 17:30 [PATCH 0/9] drivers: cacheinfo support Sudeep Holla
2014-06-25 17:30 ` Sudeep Holla
2014-06-25 17:30 ` Sudeep Holla
2014-06-25 17:30 ` Sudeep Holla
2014-06-25 17:30 ` [PATCH 1/9] drivers: base: add new class "cpu" to group cpu devices Sudeep Holla
2014-06-25 17:30 ` [PATCH 2/9] drivers: base: support cpu cache information interface to userspace via sysfs Sudeep Holla
2014-06-25 17:30   ` Sudeep Holla
2014-06-25 17:30   ` Sudeep Holla
2014-06-25 17:30   ` Sudeep Holla
2014-06-25 22:23   ` Russell King - ARM Linux
2014-06-25 22:23     ` Russell King - ARM Linux
2014-06-25 22:23     ` Russell King - ARM Linux
2014-06-25 22:23     ` Russell King - ARM Linux
2014-06-26 18:41     ` Sudeep Holla
2014-06-26 18:41       ` Sudeep Holla
2014-06-26 18:41       ` Sudeep Holla
2014-06-26 18:41       ` Sudeep Holla
2014-06-26 18:41       ` Sudeep Holla
2014-06-26 18:50       ` Russell King - ARM Linux
2014-06-26 18:50         ` Russell King - ARM Linux
2014-06-26 18:50         ` Russell King - ARM Linux
2014-06-26 18:50         ` Russell King - ARM Linux
2014-06-26 18:50         ` Russell King - ARM Linux
2014-06-26 19:03         ` Sudeep Holla
2014-06-26 19:03           ` Sudeep Holla
2014-06-26 19:03           ` Sudeep Holla
2014-06-26 19:03           ` Sudeep Holla
2014-06-26 19:03           ` Sudeep Holla
2014-07-10  0:09   ` Greg Kroah-Hartman
2014-07-10  0:09     ` Greg Kroah-Hartman
2014-07-10  0:09     ` Greg Kroah-Hartman
2014-07-10  0:09     ` Greg Kroah-Hartman
2014-07-10 13:37     ` Sudeep Holla [this message]
2014-07-10 13:37       ` Sudeep Holla
2014-07-10 13:37       ` Sudeep Holla
2014-07-10 13:37       ` Sudeep Holla
2014-07-10 13:37       ` Sudeep Holla
2014-06-25 17:30 ` [PATCH 3/9] ia64: move cacheinfo sysfs to generic cacheinfo infrastructure Sudeep Holla
2014-06-25 17:30   ` Sudeep Holla
2014-06-25 17:30 ` [PATCH 4/9] s390: " Sudeep Holla
2014-06-25 17:30 ` [PATCH 5/9] x86: " Sudeep Holla
2014-06-25 17:30 ` [PATCH 6/9] powerpc: " Sudeep Holla
2014-06-25 17:30   ` Sudeep Holla
2014-06-25 17:30 ` [PATCH 7/9] ARM64: kernel: add support for cpu cache information Sudeep Holla
2014-06-25 17:30   ` Sudeep Holla
2014-06-27 10:36   ` Mark Rutland
2014-06-27 10:36     ` Mark Rutland
2014-06-27 11:22     ` Sudeep Holla
2014-06-27 11:22       ` Sudeep Holla
2014-06-27 11:34       ` Mark Rutland
2014-06-27 11:34         ` Mark Rutland
2014-06-25 17:30 ` [PATCH 8/9] ARM: " Sudeep Holla
2014-06-25 17:30   ` Sudeep Holla
2014-06-25 22:33   ` Russell King - ARM Linux
2014-06-25 22:33     ` Russell King - ARM Linux
2014-06-26 11:33     ` Sudeep Holla
2014-06-26 11:33       ` Sudeep Holla
2014-06-26  0:19   ` Stephen Boyd
2014-06-26  0:19     ` Stephen Boyd
2014-06-26 11:36     ` Sudeep Holla
2014-06-26 11:36       ` Sudeep Holla
2014-06-26 18:45       ` Stephen Boyd
2014-06-26 18:45         ` Stephen Boyd
2014-06-27  9:38         ` Sudeep Holla
2014-06-27  9:38           ` Sudeep Holla
2014-06-25 17:30 ` [PATCH 9/9] ARM: kernel: add outer cache support for cacheinfo implementation Sudeep Holla
2014-06-25 17:30   ` Sudeep Holla
2014-06-25 22:37   ` Russell King - ARM Linux
2014-06-25 22:37     ` Russell King - ARM Linux
2014-06-26 13:02     ` Sudeep Holla
2014-06-26 13:02       ` Sudeep Holla
2014-07-25 16:44 ` [PATCH v2 0/9] drivers: cacheinfo support Sudeep Holla
2014-07-25 16:44   ` Sudeep Holla
2014-07-25 16:44   ` Sudeep Holla
2014-07-25 16:44   ` [PATCH v2 1/9] drivers: base: add new class "cpu" to group cpu devices Sudeep Holla
2014-07-25 19:09     ` Stephen Boyd
2014-07-28 13:37       ` Sudeep Holla
2014-07-25 16:44   ` [PATCH v2 2/9] drivers: base: support cpu cache information interface to userspace via sysfs Sudeep Holla
2014-07-29 23:09     ` Stephen Boyd
2014-07-30 16:23       ` Sudeep Holla
2014-07-31 19:46         ` Stephen Boyd
2014-08-05 18:15           ` Sudeep Holla
2014-07-25 16:44   ` [PATCH v2 3/9] ia64: move cacheinfo sysfs to generic cacheinfo infrastructure Sudeep Holla
2014-07-25 16:44     ` Sudeep Holla
2014-07-25 16:44   ` [PATCH v2 4/9] s390: " Sudeep Holla
2014-07-25 16:44   ` [PATCH v2 5/9] x86: " Sudeep Holla
2014-07-25 16:44   ` [PATCH v2 6/9] powerpc: " Sudeep Holla
2014-07-25 16:44     ` Sudeep Holla
2014-07-25 16:44   ` [PATCH v2 7/9] ARM64: kernel: add support for cpu cache information Sudeep Holla
2014-07-25 16:44     ` Sudeep Holla
2014-07-25 16:44   ` [PATCH v2 8/9] ARM: " Sudeep Holla
2014-07-25 16:44     ` Sudeep Holla
2014-07-25 16:44   ` [PATCH v2 9/9] ARM: kernel: add outer cache support for cacheinfo implementation Sudeep Holla
2014-07-25 16:44     ` Sudeep Holla
2014-08-21 10:59   ` [PATCH v3 00/11] drivers: cacheinfo support Sudeep Holla
2014-08-21 10:59     ` Sudeep Holla
2014-08-21 10:59     ` Sudeep Holla
2014-08-21 10:59     ` Sudeep Holla
2014-08-21 10:59     ` [PATCH v3 01/11] cpumask: factor out show_cpumap into separate helper function Sudeep Holla
2014-08-21 10:59     ` [PATCH v3 02/11] topology: replace custom attribute macros with standard DEVICE_ATTR* Sudeep Holla
2014-08-21 10:59     ` [PATCH v3 03/11] drivers: base: add new class "cpu" to group cpu devices Sudeep Holla
2014-08-21 11:20       ` David Herrmann
2014-08-21 12:30         ` Sudeep Holla
2014-08-21 12:37           ` David Herrmann
2014-08-21 14:54             ` Sudeep Holla
2014-08-22  9:12           ` Kay Sievers
2014-08-22 11:29             ` [PATCH] drivers: base: add cpu_device_create to support per-cpu devices Sudeep Holla
2014-08-22 11:37               ` David Herrmann
2014-08-22 11:41                 ` David Herrmann
2014-08-22 12:33                   ` Sudeep Holla
2014-08-26 16:54                     ` Sudeep Holla
2014-08-26 17:08                       ` David Herrmann
2014-08-22 12:17                 ` Sudeep Holla
2014-09-02 17:22               ` Sudeep Holla
2014-09-02 17:26                 ` Greg Kroah-Hartman
2014-09-02 17:40                   ` Sudeep Holla
2014-09-02 17:55                     ` Greg Kroah-Hartman
2014-08-21 10:59     ` [PATCH v3 04/11] drivers: base: support cpu cache information interface to userspace via sysfs Sudeep Holla
2014-08-21 10:59     ` [PATCH v3 05/11] ia64: move cacheinfo sysfs to generic cacheinfo infrastructure Sudeep Holla
2014-08-21 10:59       ` Sudeep Holla
2014-08-21 10:59     ` [PATCH v3 06/11] s390: " Sudeep Holla
2014-08-21 10:59     ` [PATCH v3 07/11] x86: " Sudeep Holla
2014-08-21 10:59     ` [PATCH v3 08/11] powerpc: " Sudeep Holla
2014-08-21 10:59       ` Sudeep Holla
2014-08-21 10:59     ` [PATCH v3 09/11] ARM64: kernel: add support for cpu cache information Sudeep Holla
2014-08-21 10:59       ` Sudeep Holla
2014-08-21 10:59     ` [PATCH v3 10/11] ARM: " Sudeep Holla
2014-08-21 10:59       ` Sudeep Holla
2014-08-21 10:59     ` [PATCH v3 11/11] ARM: kernel: add outer cache support for cacheinfo implementation Sudeep Holla
2014-08-21 10:59       ` Sudeep Holla

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=53BE9713.8090700@arm.com \
    --to=sudeep.holla@arm.com \
    --cc=Lorenzo.Pieralisi@arm.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=heiko.carstens@de.ibm.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-ia64@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-s390@vger.kernel.org \
    --cc=linux390@de.ibm.com \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=robh@kernel.org \
    --cc=x86@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.