Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 21 Jan 2014 18:25:27 -0800
From:      Luigi Rizzo <rizzo@iet.unipi.it>
To:        FreeBSD Current <current@freebsd.org>
Subject:   possible selrecord optimization ?
Message-ID:  <CA%2BhQ2%2BhW4_8tkCqyUWUWR_VV%2B6Jp=t0XzVE5kaWFz=SKDd2bow@mail.gmail.com>

next in thread | raw e-mail | index | archive | help
Looking at how selrecord() / selwakeup() and their Linux counterparts
poll_wait() and wake_up() are used, i noticed the following:

- linux tends to call wake_up() unconditionally
  at the beginning of the poll handler

- FreeBSD tends to call selrecord() only when it detects a blocking
  situation, and this also requires something (a lock or a retry;
  the lock in selinfo is not good for this) to avoid the race between
  the blocking_test..selrecord pair and the selwakeup().

FreeBSD could call selrecord unconditionally (and save the extra
lock/retry), but selrecord is expensive as it queues the thread on
the struct selinfo, and this takes a lock.

I wonder if we could use the same optimization as Linux:
as soon as pollscan/selscan detects a non-blocking fd,
make selrecord a no-op (which is probably as simple
as setting SELTD_RESCAN; and since it only goes up
we do not need to lock to check it).

This way, we would pay at most for one extra selrecord per
poll/select.

Even more interesting, it could simplify the logic and locking
in poll handlers.

As an example, in sys/uipc_socket.c :: sopoll_generic()
we could completely decouple the locks on so_snd and so_rcv.

comments ?

Note that it is only an optimization, so we could write
poll handlers in the selrecord-then-test style even without it.

cheers
luigi



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CA%2BhQ2%2BhW4_8tkCqyUWUWR_VV%2B6Jp=t0XzVE5kaWFz=SKDd2bow>