Skip to contentSkip to conversation

libsensors: No longer depend on libsysfs

PATCH In review Jean Delvare 3 participants 9 messages Nov 29, 2007 – Dec 16, 2007 Library code

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 libsensors: No longer depend on libsysfs

Hi all,

Here is a proposed patch to make libsensors no longer depend on libsysfs. Instead, it accesses sysfs directly, using 3 embedded helper functions. My motivations for doing this are:
* As far as I know, libsysfs is no longer maintained.
* libsysfs does much more than we need. For example, when asking for a device attribute list, libsysfs will read the contents and permissions of all attributes. Not only does this waste CPU cycles per se, but in the case of hwmon driver it also triggers register reads, which can be slow for SMBus chips.
* libsysfs enforces the difference between devices and class devices, while future changes will be easier if we can handle both types alike.

The diffstat goes like this:

 INSTALL       |    2
 lib/Module.mk |    2
 lib/sysfs.c   |  323 ++++++++++++++++++++++++++++++++++------------------------
 3 files changed, 191 insertions(+), 136 deletions(-)

So basically ~60 lines of code are added, not really significant compared to the total number of lines of code of libsensors (6500), and also very small compared to the size of libsysfs (4500 lines of code.)

As for performance benefits, numbers speak for themselves: "sensors" is more than twice as fast as before! Just counting the sysfs part of sensors_init, the new code is 4.7x as fast as the original libsysfs-based code. I've also checked memory consumption and the improvement is very visible: the overall memory used is divided by 4 (from 1,025,281 bytes to 259,110 bytes in my example, measured using valgrind.)

Testers and comments welcome.

INSTALL +0 -2
@@ -14,11 +14,9 @@ Build-time dependencies:
 * gcc
 * bison
 * flex
-* libsysfs header files (from sysfsutils-devel)
 * rrd header files (optional, for sensord)
 
 Run-time dependencies:
-* libsysfs (from sysfsutils)
 * perl (for sensors-detect)
 * rrd (optional, for sensord)
 * proper kernel configuration (see below)
lib/Module.mk +1 -1
@@ -59,7 +59,7 @@ LIBHEADERFILES := $(MODULE_DIR)/error.h 
 
 # How to create the shared library
 $(MODULE_DIR)/$(LIBSHLIBNAME): $(LIBSHOBJECTS)
-	$(CC) -shared -Wl,-soname,$(LIBSHSONAME) -o $@ $^ -lc -lm -lsysfs
+	$(CC) -shared -Wl,-soname,$(LIBSHSONAME) -o $@ $^ -lc -lm
 
 $(MODULE_DIR)/$(LIBSHSONAME): $(MODULE_DIR)/$(LIBSHLIBNAME)
 	$(RM) $@
lib/sysfs.c +190 -133

448 lines not on this page · raw message

Signature · 6 lines
Jean Delvare

_______________________________________________
lm-sensors mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors
#1 lore raw
Quoted 14 lines · Jean Delvare

Hi all,

Here is a proposed patch to make libsensors no longer depend on libsysfs. Instead, it accesses sysfs directly, using 3 embedded helper functions. My motivations for doing this are:
* As far as I know, libsysfs is no longer maintained.
* libsysfs does much more than we need. For example, when asking for a device attribute list, libsysfs will read the contents and permissions of all attributes. Not only does this waste CPU cycles per se, but in the case of hwmon driver it also triggers register reads, which can be slow for SMBus chips.
* libsysfs enforces the difference between devices and class devices, while future changes will be easier if we can handle both types alike.

Good work!

I'm afraid I don't have the time to review this atm though, any other takers?

Regards,

Hans

_______________________________________________
lm-sensors mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

#2 lore raw
In reply to Jean Delvare

Hi Hans,

Quoted 16 lines · Hans de Goede
Quoted 14 lines · Jean Delvare

Hi all,

Here is a proposed patch to make libsensors no longer depend on libsysfs. Instead, it accesses sysfs directly, using 3 embedded helper functions. My motivations for doing this are:
* As far as I know, libsysfs is no longer maintained.
* libsysfs does much more than we need. For example, when asking for a device attribute list, libsysfs will read the contents and permissions of all attributes. Not only does this waste CPU cycles per se, but in the case of hwmon driver it also triggers register reads, which can be slow for SMBus chips.
* libsysfs enforces the difference between devices and class devices, while future changes will be easier if we can handle both types alike.

Quoted 3 lines

Good work!

I'm afraid I don't have the time to review this atm though, any other takers?

If you have the possibility to test the patch, that would be appreciated as well, and less time-consuming than a review. Different kernel versions and configurations can make the sysfs tree look a bit different. Also, i2c and non-i2c chips have different code paths. I've tested as much as I could on my systems, but more testing can't hurt.

Thanks,

Signature · 6 lines
Jean Delvare

_______________________________________________
lm-sensors mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors
#3 lore raw
In reply to Jean Delvare
Quoted 20 lines · Jean Delvare

Hi Hans,

Quoted 17 lines · Hans de Goede
Quoted 14 lines · Jean Delvare

Hi all,

Here is a proposed patch to make libsensors no longer depend on libsysfs. Instead, it accesses sysfs directly, using 3 embedded helper functions. My motivations for doing this are:
* As far as I know, libsysfs is no longer maintained.
* libsysfs does much more than we need. For example, when asking for a device attribute list, libsysfs will read the contents and permissions of all attributes. Not only does this waste CPU cycles per se, but in the case of hwmon driver it also triggers register reads, which can be slow for SMBus chips.
* libsysfs enforces the difference between devices and class devices, while future changes will be easier if we can handle both types alike.

Good work!

Quoted 8 lines
Quoted 1 line

I'm afraid I don't have the time to review this atm though, any other takers?

If you have the possibility to test the patch, that would be appreciated as well, and less time-consuming than a review. Different kernel versions and configurations can make the sysfs tree look a bit different. Also, i2c and non-i2c chips have different code paths. I've tested as much as I could on my systems, but more testing can't hurt.

I've just given it a test run on my abituguru machine, works fine. Tomorrow I'll give it a test run on a FSC machine.

If you're reasonably sure this patch is ok, I could put it in the Fedora Rawhide / devel package for some greater exposure, then we can be pretty sure there will be plenty of testing before we release 3.0.1 .

Regards,

Hans

_______________________________________________
lm-sensors mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

#4 lore raw
In reply to Jean Delvare

Hi Hans,

Quoted 9 lines · Hans de Goede
Quoted 5 lines · Jean Delvare

If you have the possibility to test the patch, that would be appreciated as well, and less time-consuming than a review. Different kernel versions and configurations can make the sysfs tree look a bit different. Also, i2c and non-i2c chips have different code paths. I've tested as much as I could on my systems, but more testing can't hurt.

I've just given it a test run on my abituguru machine, works fine. Tomorrow I'll give it a test run on a FSC machine.

OK, thanks.

Quoted 3 lines

If you're reasonably sure this patch is ok, I could put it in the Fedora Rawhide / devel package for some greater exposure, then we can be pretty sure there will be plenty of testing before we release 3.0.1 .

Well, I have no reason to believe that anything is wrong with this patch, as all my testing has been successful. Feel free to apply it to Rawhide if you want. I would like to commit the change soon, the only thing I am waiting for at the moment is Mark's ack, as we had been discussing the matter before, he might want to comment on the approach I took in my patch.

Signature · 6 lines
Jean Delvare

_______________________________________________
lm-sensors mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors
#5 lore raw
In reply to Jean Delvare
Quoted 6 lines · Jean Delvare

Well, I have no reason to believe that anything is wrong with this patch, as all my testing has been successful. Feel free to apply it to Rawhide if you want. I would like to commit the change soon, the only thing I am waiting for at the moment is Mark's ack, as we had been discussing the matter before, he might want to comment on the approach I took in my patch.

Patch is committed now.

Signature · 6 lines
Jean Delvare

_______________________________________________
lm-sensors mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors
#6 lore raw
In reply to Jean Delvare

Hi Jean:

Quoted 9 lines · Jean Delvare
Quoted 6 lines · Jean Delvare

Well, I have no reason to believe that anything is wrong with this patch, as all my testing has been successful. Feel free to apply it to Rawhide if you want. I would like to commit the change soon, the only thing I am waiting for at the moment is Mark's ack, as we had been discussing the matter before, he might want to comment on the approach I took in my patch.

Patch is committed now.

I've finally finished reviewing this. I only have one minor change to suggest, which IMHO makes the code a little more readable at very little expense in cycles and no expense in size.

Index: lib/sysfs.c
=================================--- lib/sysfs.c (revision 5072)
+++ lib/sysfs.c (working copy)
@@ -73,7 +73,7 @@
* local errors, or a negative error value if any call fails. */
static int sysfs_foreach_classdev(const char *class_name,
- int (*func)(char *, const char*))
+ int (*func)(const char *, const char *))
{
char path[NAME_MAX];
int path_off, ret;
@@ -105,7 +105,7 @@
* local errors, or a negative error value if any call fails. */
static int sysfs_foreach_busdev(const char *bus_type,
- int (*func)(char *, const char*))
+ int (*func)(const char *, const char *))
{
char path[NAME_MAX];
int path_off, ret;
@@ -455,7 +455,7 @@
}

/* returns: 0 if successful, !0 otherwise */
-static int sensors_read_one_sysfs_chip(char *dev_path, const char *dev_name) +static int sensors_read_one_sysfs_chip(const char *dev_path, const char *dev_name)
{
int domain, bus, slot, fn;
int err = -SENSORS_ERR_KERNEL;
@@ -539,20 +539,20 @@
return 0;
}

-static int sensors_add_hwmon_device(char *path, const char *classdev) +static int sensors_add_hwmon_device(const char *path, const char *classdev)
{
+ char linkpath[NAME_MAX];
char device[NAME_MAX];
- int path_off = strlen(path);
int dev_len;
(void)classdev; /* hide warning */

- snprintf(path + path_off, NAME_MAX - path_off, "/device");
- dev_len = readlink(path, device, NAME_MAX - 1);
+ snprintf(linkpath, NAME_MAX, "%s/device", path);
+ dev_len = readlink(linkpath, device, NAME_MAX - 1);
if (dev_len < 0)
return -SENSORS_ERR_KERNEL;
device[dev_len] = '\0';

- return sensors_read_one_sysfs_chip(path, strrchr(device, '/') + 1);
+ return sensors_read_one_sysfs_chip(linkpath, strrchr(device, '/') + 1);
}

/* returns 0 if successful, !0 otherwise */
@@ -572,7 +572,7 @@
}

/* returns 0 if successful, !0 otherwise */
-static int sensors_add_i2c_bus(char *path, const char *classdev) +static int sensors_add_i2c_bus(const char *path, const char *classdev)
{
sensors_bus entry;

Signature · 8 lines
Mark M. Hoffman
[email protected]


_______________________________________________
lm-sensors mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors
#7 lore raw
In reply to Jean Delvare

Hi Mark,

Quoted 74 lines · Mark M. Hoffman

Hi Jean:

Quoted 9 lines · Jean Delvare
Quoted 6 lines · Jean Delvare

Well, I have no reason to believe that anything is wrong with this patch, as all my testing has been successful. Feel free to apply it to Rawhide if you want. I would like to commit the change soon, the only thing I am waiting for at the moment is Mark's ack, as we had been discussing the matter before, he might want to comment on the approach I took in my patch.

Patch is committed now.

I've finally finished reviewing this. I only have one minor change to suggest, which IMHO makes the code a little more readable at very little expense in cycles and no expense in size.

Index: lib/sysfs.c
=================================> --- lib/sysfs.c (revision 5072)
+++ lib/sysfs.c (working copy)

lib/sysfs.c +8 -8
@@ -73,7 +73,7 @@
  * local errors, or a negative error value if any call fails.
  */
 static int sysfs_foreach_classdev(const char *class_name,
-				   int (*func)(char *, const char*))
+				   int (*func)(const char *, const char *))
 {
 	char path[NAME_MAX];
 	int path_off, ret;
@@ -105,7 +105,7 @@
  * local errors, or a negative error value if any call fails.
  */
 static int sysfs_foreach_busdev(const char *bus_type,
-				 int (*func)(char *, const char*))
+				 int (*func)(const char *, const char *))
 {
 	char path[NAME_MAX];
 	int path_off, ret;
@@ -455,7 +455,7 @@
 }
 
 /* returns: 0 if successful, !0 otherwise */
-static int sensors_read_one_sysfs_chip(char *dev_path, const char *dev_name)
+static int sensors_read_one_sysfs_chip(const char *dev_path, const char *dev_name)
 {
 	int domain, bus, slot, fn;
 	int err = -SENSORS_ERR_KERNEL;
@@ -539,20 +539,20 @@
 	return 0;
 }
 
-static int sensors_add_hwmon_device(char *path, const char *classdev)
+static int sensors_add_hwmon_device(const char *path, const char *classdev)
 {
+	char linkpath[NAME_MAX];
 	char device[NAME_MAX];
-	int path_off = strlen(path);
 	int dev_len;
 	(void)classdev; /* hide warning */
 
-	snprintf(path + path_off, NAME_MAX - path_off, "/device");
-	dev_len = readlink(path, device, NAME_MAX - 1);
+	snprintf(linkpath, NAME_MAX, "%s/device", path);
+	dev_len = readlink(linkpath, device, NAME_MAX - 1);
 	if (dev_len < 0)
 		return -SENSORS_ERR_KERNEL;
 	device[dev_len] = '\0';
 
-	return sensors_read_one_sysfs_chip(path, strrchr(device, '/') + 1);
+	return sensors_read_one_sysfs_chip(linkpath, strrchr(device, '/') + 1);
 }
 
 /* returns 0 if successful, !0 otherwise */

lib/sysfs.c line 578

Quoted 8 lines
lib/sysfs.c +1 -1
@@ -572,7 +572,7 @@
 }
 
 /* returns 0 if successful, !0 otherwise */
-static int sensors_add_i2c_bus(char *path, const char *classdev)
+static int sensors_add_i2c_bus(const char *path, const char *classdev)
 {
 	sensors_bus entry;
 

I'm totally fine with this patch, I agree that it's somewhat cleaner and the additional cost is negligible. Feel free to apply it to SVN.

Thanks for the review,

Signature · 6 lines
Jean Delvare

_______________________________________________
lm-sensors mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors
#8 lore raw
In reply to Jean Delvare

Hi Jean:

Quoted 4 lines · Mark M. Hoffman
Quoted 3 lines

I've finally finished reviewing this. I only have one minor change to suggest, which IMHO makes the code a little more readable at very little expense in cycles and no expense in size.

Quoted 4 lines · Jean Delvare

I'm totally fine with this patch, I agree that it's somewhat cleaner and the additional cost is negligible. Feel free to apply it to SVN.

Thanks for the review,

You're welcome; committed.

And BTW thanks for doing the work to get rid of libsysfs.

Regards,

Signature · 8 lines
Mark M. Hoffman
[email protected]


_______________________________________________
lm-sensors mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors