linux-hotplug.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Kay Sievers <kay.sievers@vrfy.org>
To: linux-hotplug@vger.kernel.org
Subject: Re: [UDEV, PATCH] Add profiling support to Makefile
Date: Tue, 15 Feb 2005 09:12:56 +0000	[thread overview]
Message-ID: <1108458776.7914.32.camel@localhost.localdomain> (raw)
In-Reply-To: <200502131716.55756.mbuesch@freenet.de>

[-- Attachment #1: Type: text/plain, Size: 1174 bytes --]

On Tue, 2005-02-15 at 09:45 +0100, Michael Buesch wrote:
>Quoting Greg KH <greg@kroah.com>:
>> On Sun, Feb 13, 2005 at 05:16:51PM +0100, Michael Buesch wrote:
>> > Hi,
>> > 
>> > This patch adds an option to the Makefile to enable
>> > profiling. Profiling is only enabled, when not building
>> > against klibc, as klibc lacks support for mcount().
>> > 
>> > Please apply. Thanks.
>> 
>> You forgot to update the documentation about this option, so I'll hold
>> off till you redo that :)
>
>Oops. :O Here it is.
>
>> Also, what has profiling information helped you out with in udev?  Found
>> anything interesting?  Or are you just using it for coverage analysis
>> (which is a flawed thing, but that's another topic...)
>
>I did not do much testing, yet, because of missing time.
>But I will do that.
>My first testrun showed that the namedev matchrule function and the udevdb
>are the slowest parts of the whole executable. So maybe there's some
>optimization possible. But I'll look closer at it later.

The biggest part of it seems libsysfs. A replacement of the attribute
reading functions with a simple open() gives ~20% speed increase for
udevstart on my box.

Kay 

[-- Attachment #2: udev-no-libsysfs-attr-read-01.patch --]
[-- Type: text/x-patch, Size: 8963 bytes --]

===== namedev.c 1.180 vs edited =====
--- 1.180/namedev.c	2005-02-13 22:03:06 +01:00
+++ edited/namedev.c	2005-02-15 10:02:15 +01:00
@@ -36,13 +36,16 @@
 #include "libsysfs/sysfs/libsysfs.h"
 #include "list.h"
 #include "udev.h"
+#include "udev_sysfs.h"
 #include "udev_utils.h"
 #include "udev_version.h"
 #include "logging.h"
 #include "namedev.h"
 #include "udev_db.h"
 
-static struct sysfs_attribute *find_sysfs_attribute(struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device, char *attr);
+static int find_sysfs_attribute(struct sysfs_class_device *class_dev,
+				struct sysfs_device *sysfs_device, const char *attr,
+				char *value, size_t vlen);
 
 /* compare string with pattern (supports * ? [0-9] [!A-Z]) */
 static int strcmp_pattern(const char *p, const char *s)
@@ -182,7 +185,6 @@
 	char *spos;
 	char *rest;
 	int slen;
-	struct sysfs_attribute *tmpattr;
 	unsigned int next_free_number;
 	struct sysfs_class_device *class_dev_parent;
 
@@ -265,27 +267,26 @@
 			break;
 		case 's':
 			if (attr != NULL) {
-				tmpattr = find_sysfs_attribute(class_dev, sysfs_device, attr);
-				if (tmpattr == NULL) {
-					dbg("sysfa attribute '%s' not found", attr);
+				char value[VALUE_SIZE];
+
+				if (find_sysfs_attribute(class_dev, sysfs_device, attr, value, sizeof(value)) != 0) {
+					dbg("sysfs attribute '%s' not found", attr);
 					break;
 				}
 				/* strip trailing whitespace of matching value */
-				if (isspace(tmpattr->value[strlen(tmpattr->value)-1])) {
-					i = len = strlen(tmpattr->value);
-					while (i > 0 &&  isspace(tmpattr->value[i-1]))
+				if (isspace(value[strlen(value)-1])) {
+					i = len = strlen(value);
+					while (i > 0 &&  isspace(value[i-1]))
 						i--;
 					if (i < len) {
-						tmpattr->value[i] = '\0';
-						dbg("remove %i trailing whitespace chars from '%s'",
-							 len - i, tmpattr->value);
+						value[i] = '\0';
+						dbg("remove %i trailing whitespace chars from '%s'", len - i, value);
 					}
 				}
-				strfieldcatmax(string, tmpattr->value, maxsize);
-				dbg("substitute sysfs value '%s'", tmpattr->value);
-			} else {
+				strfieldcatmax(string, value, maxsize);
+				dbg("substitute sysfs value '%s'", value);
+			} else
 				dbg("missing attribute");
-			}
 			break;
 		case '%':
 			strfieldcatmax(string, "%", maxsize);
@@ -448,67 +449,64 @@
 	return retval;
 }
 
-static struct sysfs_attribute *find_sysfs_attribute(struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device, char *attr)
+static int find_sysfs_attribute(struct sysfs_class_device *class_dev,
+				struct sysfs_device *sysfs_device, const char *attr,
+				char *value, size_t vlen)
 {
-	struct sysfs_attribute *tmpattr = NULL;
 	char *c;
 
-	dbg("look for device attribute '%s'", attr);
+	dbg("look for class device attribute '%s'", attr);
 	/* try to find the attribute in the class device directory */
-	tmpattr = sysfs_get_classdev_attr(class_dev, attr);
-	if (tmpattr)
+	if (sysfs_read_attr(class_dev->path, attr, value, vlen) == 0)
 		goto attr_found;
 
 	/* look in the class device directory if present */
 	if (sysfs_device) {
-		tmpattr = sysfs_get_device_attr(sysfs_device, attr);
-		if (tmpattr)
+		dbg("look for devices device attribute '%s'", attr);
+		if (sysfs_read_attr(sysfs_device->path, attr, value, vlen) == 0)
 			goto attr_found;
 	}
 
-	return NULL;
+	return -1;
 
 attr_found:
-	c = strchr(tmpattr->value, '\n');
+	c = strchr(value, '\n');
 	if (c != NULL)
 		c[0] = '\0';
 
-	dbg("found attribute '%s'", tmpattr->path);
-	return tmpattr;
+	dbg("found attribute '%s'", attr);
+	return 0;
 }
 
 static int compare_sysfs_attribute(struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device, struct sysfs_pair *pair)
 {
-	struct sysfs_attribute *tmpattr;
+	char value[VALUE_SIZE];
 	int i;
 	int len;
 
-	if ((pair == NULL) || (pair->file[0] == '\0') || (pair->value == '\0'))
+	if ((pair == NULL) || (pair->file[0] == '\0') || (pair->value[0] == '\0'))
 		return -ENODEV;
 
-	tmpattr = find_sysfs_attribute(class_dev, sysfs_device, pair->file);
-	if (tmpattr == NULL)
+	if (find_sysfs_attribute(class_dev, sysfs_device, pair->file, value, sizeof(value)) != 0)
 		return -ENODEV;
 
 	/* strip trailing whitespace of value, if not asked to match for it */
 	if (! isspace(pair->value[strlen(pair->value)-1])) {
-		i = len = strlen(tmpattr->value);
-		while (i > 0 &&  isspace(tmpattr->value[i-1]))
+		i = len = strlen(value);
+		while (i > 0 &&  isspace(value[i-1]))
 			i--;
 		if (i < len) {
-			tmpattr->value[i] = '\0';
+			value[i] = '\0';
 			dbg("remove %i trailing whitespace chars from '%s'",
-			    len - i, tmpattr->value);
+			    len - i, value);
 		}
 	}
 
-	dbg("compare attribute '%s' value '%s' with '%s'",
-		  pair->file, tmpattr->value, pair->value);
-	if (strcmp_pattern(pair->value, tmpattr->value) != 0)
+	dbg("compare attribute '%s' value '%s' with '%s'", pair->file, value, pair->value);
+	if (strcmp_pattern(pair->value, value) != 0)
 		return -ENODEV;
 
-	dbg("found matching attribute '%s' with value '%s'",
-	    pair->file, pair->value);
+	dbg("found matching attribute '%s' with value '%s'", pair->file, pair->value);
 	return 0;
 }
 
===== udev_add.c 1.93 vs edited =====
--- 1.93/udev_add.c	2005-02-13 22:03:06 +01:00
+++ edited/udev_add.c	2005-02-15 10:02:15 +01:00
@@ -38,6 +38,7 @@
 
 #include "libsysfs/sysfs/libsysfs.h"
 #include "udev.h"
+#include "udev_sysfs.h"
 #include "udev_utils.h"
 #include "udev_version.h"
 #include "logging.h"
@@ -51,14 +52,13 @@
  */
 static int get_major_minor(struct sysfs_class_device *class_dev, struct udevice *udev)
 {
-	struct sysfs_attribute *attr = NULL;
+	char value[VALUE_SIZE];
 
-	attr = sysfs_get_classdev_attr(class_dev, "dev");
-	if (attr == NULL)
+	if (sysfs_read_attr(class_dev->path, "dev", value, sizeof(value)) != 0)
 		goto error;
-	dbg("dev='%s'", attr->value);
+	dbg("dev='%s'", value);
 
-	if (sscanf(attr->value, "%u:%u", &udev->major, &udev->minor) != 2)
+	if (sscanf(value, "%u:%u", &udev->major, &udev->minor) != 2)
 		goto error;
 	dbg("found major=%d, minor=%d", udev->major, udev->minor);
 
@@ -195,13 +195,12 @@
 
 	/* create all_partitions if requested */
 	if (udev->partitions) {
-		struct sysfs_attribute *attr;
+		char value[VALUE_SIZE];
 		int range;
 
 		/* take the maximum registered minor range */
-		attr = sysfs_get_classdev_attr(class_dev, "range");
-		if (attr) {
-			range = atoi(attr->value);
+		if (sysfs_read_attr(class_dev->path, "range", value, sizeof(value)) == 0) {
+			range = atoi(value);
 			if (range > 1)
 				udev->partitions = range-1;
 		}
===== udev_sysfs.c 1.22 vs edited =====
--- 1.22/udev_sysfs.c	2005-02-04 18:38:55 +01:00
+++ edited/udev_sysfs.c	2005-02-15 10:02:15 +01:00
@@ -26,6 +26,7 @@
 #include <string.h>
 #include <ctype.h>
 #include <errno.h>
+#include <fcntl.h>
 #include <sys/stat.h>
 
 #include "libsysfs/sysfs/libsysfs.h"
@@ -33,6 +34,27 @@
 #include "udev_sysfs.h"
 #include "udev_utils.h"
 #include "logging.h"
+
+int sysfs_read_attr(const char *path, const char *attr, char *value, size_t vlen)
+{
+	char file[SYSFS_PATH_MAX];
+	int  fd;
+	ssize_t len;
+
+	snprintf(file, SYSFS_PATH_MAX, "%s/%s", path, attr);
+	file[SYSFS_PATH_MAX-1] = '\0';
+
+	fd = open(file, O_RDONLY);
+	if (fd <0)
+		return -1;
+
+	len = read(fd, value, vlen);
+	if (len <= 0)
+		return -1;
+	value[len-1] = '\0';
+
+	return 0;
+}
 
 /* list of subsystem specific files, NULL if there is no file to wait for */
 static const struct subsystem_file {
===== udev_sysfs.h 1.2 vs edited =====
--- 1.2/udev_sysfs.h	2004-11-13 04:36:46 +01:00
+++ edited/udev_sysfs.h	2005-02-15 10:02:16 +01:00
@@ -27,6 +27,9 @@
 #define WAIT_MAX_SECONDS		5
 #define WAIT_LOOP_PER_SECOND		20
 
+/* libsysfs overkill replacement */
+extern int sysfs_read_attr(const char *path, const char *attr, char *value, size_t vlen);
+
 extern int subsystem_expect_no_dev(const char *subsystem);
 
 /* /sys/class /sys/block devices */
===== libsysfs/sysfs_utils.c 1.14 vs edited =====
--- 1.14/libsysfs/sysfs_utils.c	2004-10-20 05:15:26 +02:00
+++ edited/libsysfs/sysfs_utils.c	2005-02-15 10:02:16 +01:00
@@ -109,20 +109,25 @@
  */
 int sysfs_get_mnt_path(char *mnt_path, size_t len)
 {
-	char *sysfs_path = NULL;
+	static char path[SYSFS_PATH_MAX] = "";
+	char *sysfs_path;
 	int ret = 0;
 
 	if (mnt_path == NULL || len == 0) {
 		errno = EINVAL;
 		return -1;
 	}
-	sysfs_path = getenv(SYSFS_PATH_ENV);
-	if (sysfs_path != NULL) {
-		safestrcpymax(mnt_path, sysfs_path, len);
-		if ((sysfs_remove_trailing_slash(mnt_path)) != 0)
-			return 1;
-	} else
-		ret = sysfs_get_fs_mnt_path(SYSFS_FSTYPE_NAME, mnt_path, len);
+
+	if (path[0] == '\0') {
+		sysfs_path = getenv(SYSFS_PATH_ENV);
+		if (sysfs_path != NULL) {
+			safestrcpy(path, sysfs_path);
+			if ((sysfs_remove_trailing_slash(path)) != 0)
+				return 1;
+		} else
+			ret = sysfs_get_fs_mnt_path(SYSFS_FSTYPE_NAME, path, sizeof(path));
+	}
+	safestrcpymax(mnt_path, path, len);
 
 	return ret;
 }

  parent reply	other threads:[~2005-02-15  9:12 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-02-13 16:16 [UDEV, PATCH] Add profiling support to Makefile Michael Buesch
2005-02-15  3:54 ` Greg KH
2005-02-15  8:45 ` Michael Buesch
2005-02-15  9:12 ` Kay Sievers [this message]
2005-02-15 23:10 ` Greg KH

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=1108458776.7914.32.camel@localhost.localdomain \
    --to=kay.sievers@vrfy.org \
    --cc=linux-hotplug@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).