[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1329309727.2437.13.camel@edumazet-HP-Compaq-6005-Pro-SFF-PC>
Date: Wed, 15 Feb 2012 13:42:07 +0100
From: Eric Dumazet <eric.dumazet@...il.com>
To: Piergiorgio Beruto <piergiorgio.beruto@...il.com>
Cc: davem@...emloft.net, netdev@...r.kernel.org
Subject: Re: Possible bugfix for AF_UNIX, SOCK_SEQPACKET sockets
Le mercredi 15 février 2012 à 11:43 +0100, Piergiorgio Beruto a écrit :
> Yes, there's nothing that "doesn't work", it's a matter of performance
> (I am working on strong embedded so I'm quite concerned about both
> memory usage and "speed").
>
> The problem is that when the socket queue is filled with short sized
> packets, dequeue operation would allocate a lot of "big" chunks of
> memory, progressively smaller (first one the size of the queue, second
> one = queue size - first packet size and so on).
>
> Besides the waste of memory, you get less perfromance as malloc()
> would use the heap or mmap() depending on the size of the chunk
> (usually 64 bytes) and the use of mmap is more memory efficient but
> quite slower.
I see
> Ok, that's why I asked :) But if you agree with my objection regarding
> performance, what about adding a brand new (linux only) ioctl which
> implements the other behaviour? So the code would look something like
> this:
>
> case SIOCINQ:
> case SIOCPSZ: //// new packet size ioctl
> {
> struct sk_buff *skb;
>
> if (sk->sk_state == TCP_LISTEN) {
> err = -EINVAL;
> break;
> }
>
> spin_lock(&sk->sk_receive_queue.lock);
> if ((sk->sk_type == SOCK_STREAM ||
> sk->sk_type == SOCK_SEQPACKET) &&
> ioctl_code != SIOCPSZ) { //// have SIOCPSZ
> behave as for datagram sockets
> skb_queue_walk(&sk->sk_receive_queue, skb)
> amount += skb->len;
> } else {
> skb = skb_peek(&sk->sk_receive_queue);
> if (skb)
> amount = skb->len;
> }
> spin_unlock(&sk->sk_receive_queue.lock);
> err = put_user(amount, (int __user *)arg);
> break;
> }
ioctl() are deprecated, and such a change has ramification (for example
on strace tool)
You could use a recvmsg( ... MSG_PEEK|MSG_TRUNC) to get size of next
packet (passing a small buffer)
Ah... it seems af_unix doesnt handle MSG_TRUNC semantic as
UDP/RAW/NETLINK sockets do.
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 85d3bb7..70d9414 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1824,7 +1824,7 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
if (UNIXCB(skb).fp)
siocb->scm->fp = scm_fp_dup(UNIXCB(skb).fp);
}
- err = size;
+ err = (flags & MSG_TRUNC) ? skb->len : size;
scm_recv(sock, msg, siocb->scm, flags);
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists