Re: [PATCH v4 01/10] tools/libperf: introduce static poll file descriptors

2020-06-01 Thread Alexey Budankov


On 31.05.2020 21:19, Jiri Olsa wrote:
> On Mon, May 25, 2020 at 05:17:31PM +0300, Alexey Budankov wrote:
> 
> SBIP
> 
>> +int fdarray__add_stat(struct fdarray *fda, int fd, short revents)
>> +{
>> +int pos = fda->nr_stat;
>> +
>> +if (pos >= FDARRAY__STAT_ENTRIES_MAX)
>> +return -1;
>> +
>> +fda->stat_entries[pos].fd = fd;
>> +fda->stat_entries[pos].events = revents;
>> +fda->nr_stat++;
>> +
>> +return pos;
>> +}
>> +
>>  int fdarray__filter(struct fdarray *fda, short revents,
>>  void (*entry_destructor)(struct fdarray *fda, int fd, void 
>> *arg),
>>  void *arg)
>> @@ -113,7 +133,27 @@ int fdarray__filter(struct fdarray *fda, short revents,
>>  
>>  int fdarray__poll(struct fdarray *fda, int timeout)
>>  {
>> -return poll(fda->entries, fda->nr, timeout);
>> +int nr, i, pos, res;
>> +
>> +nr = fda->nr;
>> +
>> +for (i = 0; i < fda->nr_stat; i++) {
>> +if (fda->stat_entries[i].fd != -1) {
>> +pos = fdarray__add(fda, fda->stat_entries[i].fd,
>> +   fda->stat_entries[i].events);
>> +if (pos >= 0)
>> +fda->priv[pos].idx = i;
>> +}
>> +}
> 
> hum, so every time we call evlist__poll we end up in here
> adding more stuff to entries?

It depends on whether static fds were added by perf_evlist__add_pollfd_stat() 
or not.
If they weren't then poll() checks only event fds added by 
perf_evlist__add_pollfd().
If static fds have been added and there are valid (!=-1) fds still then  they 
are
appended to fds array. After return from poll() its result copied back to 
static fds
storage so fds state could be checked separately from event fds.

~Alexey


Re: [PATCH v4 01/10] tools/libperf: introduce static poll file descriptors

2020-05-31 Thread Jiri Olsa
On Mon, May 25, 2020 at 05:17:31PM +0300, Alexey Budankov wrote:

SBIP

> +int fdarray__add_stat(struct fdarray *fda, int fd, short revents)
> +{
> + int pos = fda->nr_stat;
> +
> + if (pos >= FDARRAY__STAT_ENTRIES_MAX)
> + return -1;
> +
> + fda->stat_entries[pos].fd = fd;
> + fda->stat_entries[pos].events = revents;
> + fda->nr_stat++;
> +
> + return pos;
> +}
> +
>  int fdarray__filter(struct fdarray *fda, short revents,
>   void (*entry_destructor)(struct fdarray *fda, int fd, void 
> *arg),
>   void *arg)
> @@ -113,7 +133,27 @@ int fdarray__filter(struct fdarray *fda, short revents,
>  
>  int fdarray__poll(struct fdarray *fda, int timeout)
>  {
> - return poll(fda->entries, fda->nr, timeout);
> + int nr, i, pos, res;
> +
> + nr = fda->nr;
> +
> + for (i = 0; i < fda->nr_stat; i++) {
> + if (fda->stat_entries[i].fd != -1) {
> + pos = fdarray__add(fda, fda->stat_entries[i].fd,
> +fda->stat_entries[i].events);
> + if (pos >= 0)
> + fda->priv[pos].idx = i;
> + }
> + }

hum, so every time we call evlist__poll we end up in here
adding more stuff to entries?

jirka

> +
> + res = poll(fda->entries, fda->nr, timeout);
> +
> + for (i = nr; i < fda->nr; i++)
> + fda->stat_entries[fda->priv[i].idx] = fda->entries[i];
> +
> + fda->nr = nr;
> +
> + return res;
>  }

SNIP



[PATCH v4 01/10] tools/libperf: introduce static poll file descriptors

2020-05-25 Thread Alexey Budankov


Implement adding of file descriptors to fixed size (currently 1)
storage at struct fdarray by the dedicated fdarray__add_stat().
Append the static descriptors to the array used by poll() syscall
at fdarray__poll(). Copy poll() result of the descriptors from the
array back to the storage for possible later analysis separately
from descriptors added by fdarray__add().

Signed-off-by: Alexey Budankov 
---
 tools/lib/api/fd/array.c | 42 +++-
 tools/lib/api/fd/array.h |  7 
 tools/lib/perf/evlist.c  | 11 +++
 tools/lib/perf/include/internal/evlist.h |  2 ++
 4 files changed, 61 insertions(+), 1 deletion(-)

diff --git a/tools/lib/api/fd/array.c b/tools/lib/api/fd/array.c
index 58d44d5eee31..b0027f2169c7 100644
--- a/tools/lib/api/fd/array.c
+++ b/tools/lib/api/fd/array.c
@@ -11,10 +11,16 @@
 
 void fdarray__init(struct fdarray *fda, int nr_autogrow)
 {
+   int i;
+
fda->entries = NULL;
fda->priv= NULL;
fda->nr  = fda->nr_alloc = 0;
fda->nr_autogrow = nr_autogrow;
+
+   fda->nr_stat = 0;
+   for (i = 0; i < FDARRAY__STAT_ENTRIES_MAX; i++)
+   fda->stat_entries[i].fd = -1;
 }
 
 int fdarray__grow(struct fdarray *fda, int nr)
@@ -83,6 +89,20 @@ int fdarray__add(struct fdarray *fda, int fd, short revents)
return pos;
 }
 
+int fdarray__add_stat(struct fdarray *fda, int fd, short revents)
+{
+   int pos = fda->nr_stat;
+
+   if (pos >= FDARRAY__STAT_ENTRIES_MAX)
+   return -1;
+
+   fda->stat_entries[pos].fd = fd;
+   fda->stat_entries[pos].events = revents;
+   fda->nr_stat++;
+
+   return pos;
+}
+
 int fdarray__filter(struct fdarray *fda, short revents,
void (*entry_destructor)(struct fdarray *fda, int fd, void 
*arg),
void *arg)
@@ -113,7 +133,27 @@ int fdarray__filter(struct fdarray *fda, short revents,
 
 int fdarray__poll(struct fdarray *fda, int timeout)
 {
-   return poll(fda->entries, fda->nr, timeout);
+   int nr, i, pos, res;
+
+   nr = fda->nr;
+
+   for (i = 0; i < fda->nr_stat; i++) {
+   if (fda->stat_entries[i].fd != -1) {
+   pos = fdarray__add(fda, fda->stat_entries[i].fd,
+  fda->stat_entries[i].events);
+   if (pos >= 0)
+   fda->priv[pos].idx = i;
+   }
+   }
+
+   res = poll(fda->entries, fda->nr, timeout);
+
+   for (i = nr; i < fda->nr; i++)
+   fda->stat_entries[fda->priv[i].idx] = fda->entries[i];
+
+   fda->nr = nr;
+
+   return res;
 }
 
 int fdarray__fprintf(struct fdarray *fda, FILE *fp)
diff --git a/tools/lib/api/fd/array.h b/tools/lib/api/fd/array.h
index b39557d1a88f..9bca72e80b09 100644
--- a/tools/lib/api/fd/array.h
+++ b/tools/lib/api/fd/array.h
@@ -3,6 +3,7 @@
 #define __API_FD_ARRAY__
 
 #include 
+#include 
 
 struct pollfd;
 
@@ -16,6 +17,9 @@ struct pollfd;
  *   I.e. using 'fda->priv[N].idx = * value' where N < fda->nr is ok,
  *   but doing 'fda->priv = malloc(M)' is not allowed.
  */
+
+#define FDARRAY__STAT_ENTRIES_MAX  1
+
 struct fdarray {
intnr;
intnr_alloc;
@@ -25,6 +29,8 @@ struct fdarray {
intidx;
void   *ptr;
} *priv;
+   intnr_stat;
+   struct pollfd  stat_entries[FDARRAY__STAT_ENTRIES_MAX];
 };
 
 void fdarray__init(struct fdarray *fda, int nr_autogrow);
@@ -34,6 +40,7 @@ struct fdarray *fdarray__new(int nr_alloc, int nr_autogrow);
 void fdarray__delete(struct fdarray *fda);
 
 int fdarray__add(struct fdarray *fda, int fd, short revents);
+int fdarray__add_stat(struct fdarray *fda, int fd, short revents);
 int fdarray__poll(struct fdarray *fda, int timeout);
 int fdarray__filter(struct fdarray *fda, short revents,
void (*entry_destructor)(struct fdarray *fda, int fd, void 
*arg),
diff --git a/tools/lib/perf/evlist.c b/tools/lib/perf/evlist.c
index 6a875a0f01bb..e68e4c08e7c2 100644
--- a/tools/lib/perf/evlist.c
+++ b/tools/lib/perf/evlist.c
@@ -317,6 +317,17 @@ int perf_evlist__add_pollfd(struct perf_evlist *evlist, 
int fd,
return pos;
 }
 
+int perf_evlist__add_pollfd_stat(struct perf_evlist *evlist, int fd,
+short revent)
+{
+   int pos = fdarray__add_stat(>pollfd, fd, revent | POLLERR | 
POLLHUP);
+
+   if (pos >= 0)
+   fcntl(fd, F_SETFL, O_NONBLOCK);
+
+   return pos;
+}
+
 static void perf_evlist__munmap_filtered(struct fdarray *fda, int fd,
 void *arg __maybe_unused)
 {
diff --git a/tools/lib/perf/include/internal/evlist.h 
b/tools/lib/perf/include/internal/evlist.h
index 74dc8c3f0b66..2b3b4518c05e 100644
--- a/tools/lib/perf/include/internal/evlist.h
+++ b/tools/lib/perf/include/internal/evlist.h
@@ -46,6