[dm-devel] [PATCH 08/12] libmultipath: wait one seconds for more uevents in uevent_listen() in uevents burst situations
tang.junhui at zte.com.cn
tang.junhui at zte.com.cn
Tue Dec 27 08:03:25 UTC 2016
From: tang.junhui <tang.junhui at zte.com.cn>
The more uevents are merged, the higher efficiency program will performs.
So, do not process uevents after receiving immediately in uevents burst
situations, but continue wait 1 seconds for more uevents except that too
much uevents (2048) have already been received or too much time eclipse
(60 seconds).
Change-Id: I763d491540e8114a81d12d603281540a81502742
Signed-off-by: tang.junhui <tang.junhui at zte.com.cn>
---
libmultipath/uevent.c | 35 +++++++++++++++++++++++++++++++++--
1 file changed, 33 insertions(+), 2 deletions(-)
diff --git a/libmultipath/uevent.c b/libmultipath/uevent.c
index cc10d65..b0b05e9 100644
--- a/libmultipath/uevent.c
+++ b/libmultipath/uevent.c
@@ -39,6 +39,7 @@
#include <linux/netlink.h>
#include <pthread.h>
#include <sys/mman.h>
+#include <sys/time.h>
#include <libudev.h>
#include <errno.h>
@@ -490,11 +491,37 @@ struct uevent *uevent_from_udev_device(struct udev_device *dev)
return uev;
}
+bool uevent_burst(struct timeval *start_time, int events)
+{
+ struct timeval diff_time, end_time;
+ unsigned long speed;
+ unsigned long eclipse_ms;
+
+ gettimeofday(&end_time, NULL);
+ timersub(&end_time, start_time, &diff_time);
+
+ eclipse_ms = diff_time.tv_sec * 1000 + diff_time.tv_usec / 1000;
+ if (eclipse_ms == 0)
+ return true;
+ /* max wait 60s */
+ if (eclipse_ms > 60*1000) {
+ condlog(1, "burst continued =%lu ms, stoped", eclipse_ms);
+ return false;
+ }
+
+ speed = (events * 1000) / eclipse_ms;
+ if (speed > 10)
+ return true;
+
+ return false;
+}
+
int uevent_listen(struct udev *udev)
{
int err = 2;
struct udev_monitor *monitor = NULL;
int fd, socket_flags, events;
+ struct timeval start_time;
int need_failback = 1;
int timeout = 30;
LIST_HEAD(uevlisten_tmp);
@@ -548,6 +575,7 @@ int uevent_listen(struct udev *udev)
}
events = 0;
+ gettimeofday(&start_time, NULL);
while (1) {
struct uevent *uev;
struct udev_device *dev;
@@ -562,7 +590,8 @@ int uevent_listen(struct udev *udev)
errno = 0;
fdcount = poll(&ev_poll, 1, poll_timeout);
if (fdcount && ev_poll.revents & POLLIN) {
- timeout = 0;
+ timeout = uevent_burst(&start_time, events + 1) ? 1:0;
+
dev = udev_monitor_receive_device(monitor);
if (!dev) {
condlog(0, "failed getting udev device");
@@ -578,7 +607,8 @@ int uevent_listen(struct udev *udev)
}
list_add_tail(&uev->node, &uevlisten_tmp);
events++;
- continue;
+ if(events < 2048)
+ continue;
}
if (fdcount < 0) {
if (errno == EINTR)
@@ -600,6 +630,7 @@ int uevent_listen(struct udev *udev)
pthread_mutex_unlock(uevq_lockp);
events = 0;
}
+ gettimeofday(&start_time, NULL);
timeout = 30;
}
need_failback = 0;
--
2.8.1.windows.1
More information about the dm-devel
mailing list