per file descriptor device callbacks ?

From: Luigi Rizzo <rizzo_at_iet.unipi.it>
Date: Mon, 27 Aug 2012 09:34:03 +0200
Hi,
in netmap, i am using a single name (/dev/netmap) to create multiple
independent file descriptors bound to different devices/queues,
and eventually I would like to mmap() each file descriptor to
a different kernel memory region.

This requires to track calls to open/ioctl/poll/mmap/close.
The difficulty i have is with mmap() and close(), because FreeBSD
seems to handle these calls per-cdev rather than per-file-descriptor
(for instance, no 'struct file' argument is available in mmap(), and
the d_close method is only called on the last close() on the device).

I definitely remember having a similar problem ~15 years ago
when I was doing audio drivers. I do not remember a workaround
at the time, though now the situation might be slightly different
because /dev/audio does some kind of multiplexing, and probably
even /dev/ptmx does something similar.

So I would appreciate suggestions on how can I track per-file-descriptor
calls to mmap and close (or at least achieve my goal to track
which individual file descriptors are used for mmap, and when
the descriptor is closed so the region is unmapped).

>From what I can tell:

+ open(), ioctl() and poll() are easy because the 'struct file *'
  argument is available through one of the 'struct thread' fields,
  td->td_fpop;

+ mmap() is slightly trickier: if i use the d_mmap method (which is what
  I have now, used by the device pager), the kernel does a first
  pass on the mmap() syscall where td->td_fpop is available, but
  the mapping is not installed and only access rights are checked.
  Subsequently i get some anonymous calls where the only argument
  i have is a 'struct cdev *' and the td->td_fpop is explicitly set
  to NULL.

  I am not sure if i can use a workaround for this by writing my own
  d_mmap_single callback that also installs the mappings so that
  i never fault on those pages.

+ close(), here i have no clue. sys/fs/devfs/devfs_vnops.c::devfs_close()
  seems to intercept all but the last call,
  and i do not see any way to intercept it.

thanks
luigi
Received on Mon Aug 27 2012 - 05:14:50 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:30 UTC