[openib-general] Re: [PATCH] signal driven io support for ib_uverbs
Gleb Natapov
glebn at voltaire.com
Thu Jul 7 02:07:47 PDT 2005
On Wed, Jul 06, 2005 at 02:35:03PM -0700, Roland Dreier wrote:
> How does this patch look?
Actually I take may words about f_setown() back. Kernel dose not
set it by default. So unless you set it in the kernel or from
userspace using fcntl(F_SETOWN) you don't receive SIGIO signal.
The question is what is the right way? Do it from the kernel or
left it to userspace? Parts of the kernel do f_setown() from the
kernel others don't.
Other then that the patch is working OK.
>
> Do you have a test program you're using to check SIGIO-based event
> handling? If so can you post it?
Actually I am using it as part of MPI implementation, but I've crafted
patch for asyncwatch.c to use signals. Try to comment F_SETOWN bit,
you wont get events.
Index: libibverbs/examples/asyncwatch.c
===================================================================
--- libibverbs/examples/asyncwatch.c (revision 2810)
+++ libibverbs/examples/asyncwatch.c (working copy)
@@ -39,6 +39,14 @@
#include <stdio.h>
#include <endian.h>
#include <byteswap.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <sys/types.h>
+#include <unistd.h>
+
#include <infiniband/verbs.h>
@@ -48,12 +56,120 @@ static inline uint64_t be64_to_cpu(uint6
static inline uint64_t be64_to_cpu(uint64_t x) { return x; }
#endif
+struct ibv_context *context;
+
+void async_sigaction (int sig, siginfo_t *siginfo, void *ign)
+{
+ int ret;
+ struct ibv_async_event event;
+
+ if (siginfo->si_code != POLL_IN)
+ {
+ fprintf (stderr, "siginfo->si_code == %d\n", siginfo->si_code);
+ return;
+ }
+
+ if (siginfo->si_fd != context->async_fd)
+ {
+ fprintf (stderr, "siginfo->si_fd != context->async_fd\n");
+ return;
+ }
+
+ while(!(ret = ibv_get_async_event (context, &event)))
+ {
+ printf(" event_type %d, port %d\n", event.event_type,
+ event.element.port_num);
+ }
+
+ if (errno == EAGAIN) /* no more events to process */
+ return;
+
+ /* other error */
+ fprintf (stderr, "Error in ibv_get_async_event\n");
+ exit (1);
+ return;
+}
+
+void async_event_setup (void)
+{
+ struct sigaction act;
+ int fdflags;
+
+ act.sa_sigaction = async_sigaction;
+ sigemptyset (&act.sa_mask);
+ act.sa_flags = SA_RESTART | SA_SIGINFO;
+ act.sa_restorer = NULL;
+
+ siginterrupt (SIGIO, 0); /* do not interrupt systemcalls */
+ if (sigaction (SIGIO, &act, NULL) != 0) {
+ perror ("sigaction");
+ exit (1);
+ }
+
+ fdflags = fcntl (context->async_fd, F_GETFL);
+
+ if (fdflags == -1) {
+ perror ("fcntl (F_GETFL)");
+ exit (1);
+ }
+
+ if (fcntl (context->async_fd, F_SETFL,
+ fdflags | O_NONBLOCK | O_ASYNC) == -1) {
+ perror ("fcntl (F_ETFL)");
+ exit (1);
+ }
+
+ if (fcntl (context->async_fd, F_SETSIG, SIGIO) == -1) {
+ perror ("fcntl (F_SETSIG)");
+ exit (1);
+ }
+
+ if (fcntl (context->async_fd, F_SETOWN, getpid()) == -1) {
+ perror ("fcntl (F_SETOWN)");
+ exit (1);
+ }
+}
+
+static void usage(const char *argv0)
+{
+ printf("Usage:\n");
+ printf(" %s wait for asynchronous events\n", argv0);
+ printf("\n");
+ printf("Options:\n");
+ printf(" -s, --sig wait for events using signals\n");
+}
+
int main(int argc, char *argv[])
{
struct dlist *dev_list;
struct ibv_device *ib_dev;
- struct ibv_context *context;
struct ibv_async_event event;
+ int sig = 0;
+
+ while (1)
+ {
+ int c;
+
+ static struct option long_options[] = {
+ { .name = "sig", .has_arg = 0, .val = 's' },
+ { 0 }
+ };
+
+ c = getopt_long(argc, argv, "s", long_options, NULL);
+
+ if (c == -1)
+ break;
+
+ switch (c)
+ {
+ case 's':
+ sig = 1;
+ break;
+ default:
+ usage (argv[0]);
+ return 1;
+ }
+ }
dev_list = ibv_get_devices();
@@ -75,12 +191,20 @@ int main(int argc, char *argv[])
printf("%s: async event FD %d\n",
ibv_get_device_name(ib_dev), context->async_fd);
+ if (sig)
+ async_event_setup();
+
while (1) {
- if (ibv_get_async_event(context, &event))
- return 1;
- printf(" event_type %d, port %d\n", event.event_type,
- event.element.port_num);
+ if (sig) {
+ pause ();
+ } else {
+ if (ibv_get_async_event(context, &event))
+ return 1;
+
+ printf(" event_type %d, port %d\n", event.event_type,
+ event.element.port_num);
+ }
}
return 0;
--
Gleb.
More information about the general
mailing list