[Nouveau] [PATCH 2/4] iccsense: convert to linked list

Martin Peres martin.peres at free.fr
Mon Mar 28 10:18:06 UTC 2016


On 25/03/16 13:19, Karol Herbst wrote:
> Signed-off-by: Karol Herbst <nouveau at karolherbst.de>
> ---
>   drm/nouveau/include/nvkm/subdev/iccsense.h |  4 +---
>   drm/nouveau/nouveau_hwmon.c                |  2 +-
>   drm/nouveau/nvkm/subdev/iccsense/base.c    | 32 +++++++++++++-----------------
>   drm/nouveau/nvkm/subdev/iccsense/priv.h    |  1 +
>   4 files changed, 17 insertions(+), 22 deletions(-)
>
> diff --git a/drm/nouveau/include/nvkm/subdev/iccsense.h b/drm/nouveau/include/nvkm/subdev/iccsense.h
> index c3defcd..a4c0da0 100644
> --- a/drm/nouveau/include/nvkm/subdev/iccsense.h
> +++ b/drm/nouveau/include/nvkm/subdev/iccsense.h
> @@ -3,12 +3,10 @@
>   
>   #include <core/subdev.h>
>   
> -struct nkvm_iccsense_rail;
>   struct nvkm_iccsense {
>   	struct nvkm_subdev subdev;
> -	u8 rail_count;
>   	bool data_valid;
> -	struct nvkm_iccsense_rail *rails;
> +	struct list_head rails;
>   };
>   
>   int gf100_iccsense_new(struct nvkm_device *, int index, struct nvkm_iccsense **);
> diff --git a/drm/nouveau/nouveau_hwmon.c b/drm/nouveau/nouveau_hwmon.c
> index 67edd2f..74f237b 100644
> --- a/drm/nouveau/nouveau_hwmon.c
> +++ b/drm/nouveau/nouveau_hwmon.c
> @@ -689,7 +689,7 @@ nouveau_hwmon_init(struct drm_device *dev)
>   			goto error;
>   	}
>   
> -	if (iccsense && iccsense->data_valid && iccsense->rail_count) {
> +	if (iccsense && iccsense->data_valid && !list_empty(&iccsense->rails)) {
>   		ret = sysfs_create_group(&hwmon_dev->kobj,
>   					 &hwmon_power_attrgroup);
>   		if (ret)
> diff --git a/drm/nouveau/nvkm/subdev/iccsense/base.c b/drm/nouveau/nvkm/subdev/iccsense/base.c
> index bf1b94e..6fde68d 100644
> --- a/drm/nouveau/nvkm/subdev/iccsense/base.c
> +++ b/drm/nouveau/nvkm/subdev/iccsense/base.c
> @@ -98,25 +98,21 @@ nvkm_iccsense_ina3221_read(struct nvkm_iccsense *iccsense,
>   int
>   nvkm_iccsense_read_all(struct nvkm_iccsense *iccsense)
>   {
> -	int result = 0, i;
> +	int result = 0;
> +	struct nvkm_iccsense_rail *rail;
>   
>   	if (!iccsense)
>   		return -EINVAL;
>   
> -	if (iccsense->rail_count == 0)
> -		return -ENODEV;
> -
> -	for (i = 0; i < iccsense->rail_count; ++i) {
> +	list_for_each_entry(rail, &iccsense->rails, head) {
>   		int res;
> -		struct nvkm_iccsense_rail *rail = &iccsense->rails[i];
>   		if (!rail->read)
>   			return -ENODEV;
>   
>   		res = rail->read(iccsense, rail);
> -		if (res >= 0)
> -			result += res;
> -		else
> +		if (res < 0)
>   			return res;
> +		result += res;
>   	}
>   	return result;
>   }
> @@ -125,9 +121,10 @@ static void *
>   nvkm_iccsense_dtor(struct nvkm_subdev *subdev)
>   {
>   	struct nvkm_iccsense *iccsense = nvkm_iccsense(subdev);
> +	struct nvkm_iccsense_rail *rail, *tmp;
>   
> -	if (iccsense->rails)
> -		kfree(iccsense->rails);
> +	list_for_each_entry_safe(rail, tmp, &iccsense->rails, head)
> +		kfree(rail);
The rails list is filled with invalid pointers at this point. Please add 
list_del(rail); before kfree(rail);

It has the added benefit of adding poisonous pointers that will show any 
access after freeing.
>   
>   	return iccsense;
>   }
> @@ -145,11 +142,6 @@ nvkm_iccsense_oneinit(struct nvkm_subdev *subdev)
>   	    || !stbl.nr_entry)
>   		return 0;
>   
> -	iccsense->rails = kmalloc(sizeof(*iccsense->rails) * stbl.nr_entry,
> -	                          GFP_KERNEL);
> -	if (!iccsense->rails)
> -		return -ENOMEM;
> -
>   	iccsense->data_valid = true;
>   	for (i = 0; i < stbl.nr_entry; ++i) {
>   		struct pwr_rail_t *r = &stbl.rail[i];
> @@ -184,7 +176,10 @@ nvkm_iccsense_oneinit(struct nvkm_subdev *subdev)
>   			continue;
>   		}
>   
> -		rail = &iccsense->rails[iccsense->rail_count];
> +		rail = kmalloc(sizeof(*rail), GFP_KERNEL);
> +		if (!rail)
> +			return -ENOMEM;
> +
>   		switch (extdev.type) {
>   		case NVBIOS_EXTDEV_INA209:
>   			rail->read = nvkm_iccsense_ina209_read;
> @@ -201,7 +196,7 @@ nvkm_iccsense_oneinit(struct nvkm_subdev *subdev)
>   		rail->rail = r->rail;
>   		rail->mohm = r->resistor_mohm;
>   		rail->i2c = &i2c_bus->i2c;
> -		++iccsense->rail_count;
> +		list_add_tail(&rail->head, &iccsense->rails);
>   	}
>   	return 0;
>   }
> @@ -224,6 +219,7 @@ nvkm_iccsense_new_(struct nvkm_device *device, int index,
>   {
>   	if (!(*iccsense = kzalloc(sizeof(**iccsense), GFP_KERNEL)))
>   		return -ENOMEM;
> +	INIT_LIST_HEAD(&(*iccsense)->rails);
>   	nvkm_iccsense_ctor(device, index, *iccsense);
>   	return 0;
>   }
> diff --git a/drm/nouveau/nvkm/subdev/iccsense/priv.h b/drm/nouveau/nvkm/subdev/iccsense/priv.h
> index ed398b8..e479128 100644
> --- a/drm/nouveau/nvkm/subdev/iccsense/priv.h
> +++ b/drm/nouveau/nvkm/subdev/iccsense/priv.h
> @@ -4,6 +4,7 @@
>   #include <subdev/iccsense.h>
>   
>   struct nvkm_iccsense_rail {
> +	struct list_head head;
>   	int (*read)(struct nvkm_iccsense *, struct nvkm_iccsense_rail *);
>   	struct i2c_adapter *i2c;
>   	u8 addr;



More information about the Nouveau mailing list