Discussion:
clarification regarding the need to call port_dissociate()
Nils Goroll
2010-05-18 14:00:21 UTC
Permalink
Hi,

I'm analyzing a core dump where port_associate() failed with EAGAIN. My
understanding is that the number of associated fds has reached the
process.max-port-events limit.
From another structure maintaining the fds associated, I know that the
respective limit of 64K cannot possibly have been reached.

I am thus suspecting a bug on my side going back to the following sentence in
the man page:

When an event for a PORT_SOURCE_FD object is retrieved, the
object no longer has an association with the port.

My initial understanding was that port_getn() was implicitly
port_dissociate()ing all ports, but checking the source this seems not to be the
case.

Could someone please confirm that my initial understanding was wrong and that
port_dissociate() should always be called for for every fd port_associate() had
been called?

Being at it, it would be nice if a clarification was added to the man page.

Thanks, Nils
j***@public.gmane.org
2010-05-18 19:28:09 UTC
Permalink
Hi Nils,
Post by Nils Goroll
I'm analyzing a core dump where port_associate() failed with EAGAIN. My
understanding is that the number of associated fds has reached the
process.max-port-events limit.
You can get EAGAIN in a couple of different ways. If you're getting
this error during port_associate(), chances are you've hit the
process.max-port-events limit. If you're getting this error during
port_create() instead, it's likely to be the project.max-port-ids limit.
Post by Nils Goroll
From another structure maintaining the fds associated, I know that the
respective limit of 64K cannot possibly have been reached.
Perhaps your rctls for the ports have been changed from their defaults.
You can try the following to print out this information:

$ prctl -n process.max-port-events <pid>
process: 12076: -bash
NAME PRIVILEGE VALUE FLAG ACTION RECIPIENT
process.max-port-events
privileged 65.5K - deny -
system 2.15G max deny -

$ prctl -n project.max-port-ids <pid>
process: 12076: -bash
NAME PRIVILEGE VALUE FLAG ACTION RECIPIENT
project.max-port-ids
privileged 8.19K - deny -
system 65.5K max deny -

In my case, <pid> was $$, which is why it lists bash as the process.
I'd be interested to see what the values for your application are.
Post by Nils Goroll
I am thus suspecting a bug on my side going back to the following sentence in
When an event for a PORT_SOURCE_FD object is retrieved, the
object no longer has an association with the port.
My initial understanding was that port_getn() was implicitly
port_dissociate()ing all ports, but checking the source this seems not
to be the case.
The API requires that you call port_associate(3C) after receipt of a
PORT_SOURCE_FD event. This is to re-enable the event for this port.

If you want to get into the nitty gritty of the implementation, no
port_dissociate(3C) is explicitly called by the framework when you
receive a SOURCE_FD event. Instead, the PORT_KEV_VALID flag is toggled
when the event is recieved, and again when port_associate(3C) is called.
The information about the fd is still kept in port structures in the
kernel. It's important to call port_dissociate(3C) when you're done
using a file-descriptor, since that frees the kernel resources that are
used by the kernel to track events for that fd.

If you're getting EAGAIN on port_associate(3C) and you're cycling
through a large number of different fds, it's possible that you didn't
call port_dissociate(3C) on fds that you're done watching. That could
consume enough kernel resources to prevent you from adding additional
file descriptors.
Post by Nils Goroll
Could someone please confirm that my initial understanding was wrong
and that port_dissociate() should always be called for for every fd
port_associate() had been called?
This statement isn't correct. You should call port_dissociate(3C) when
you're done watching events for a file-descriptor. However, if you'd
like to watch for more events from the same fd, all you need to do is
call port_associate(3C) after you're done processing the event from
port_get(3C) or port_getn(3C).

Hope that clarifies things somewhat.

-j
Nils Goroll
2010-05-19 08:51:43 UTC
Permalink
Hi Johansen,
Post by j***@public.gmane.org
Hope that clarifies things somewhat.
Absolutely. Thank you very much for your detailed explanation. This was really
helpful.

Nils

Loading...