Commit e427cad6 authored by Paolo Abeni's avatar Paolo Abeni Committed by David S. Miller

net: datagram: drop 'destructor' argument from several helpers

The only users for such argument are the UDP protocol and the UNIX
socket family. We can safely reclaim the accounted memory directly
from the UDP code and, after the previous patch, we can do scm
stats accounting outside the datagram helpers.

Overall this cleans up a bit some datagram-related helpers, and
avoids an indirect call per packet in the UDP receive path.

v1 -> v2:
 - call scm_stat_del() only when not peeking - Kirill
 - fix build issue with CONFIG_INET_ESPINTCP
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
Reviewed-by: default avatarKirill Tkhai <ktkhai@virtuozzo.com>
Reviewed-by: default avatarWillem de Bruijn <willemb@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7782040b
...@@ -3514,23 +3514,15 @@ int __skb_wait_for_more_packets(struct sock *sk, struct sk_buff_head *queue, ...@@ -3514,23 +3514,15 @@ int __skb_wait_for_more_packets(struct sock *sk, struct sk_buff_head *queue,
struct sk_buff *__skb_try_recv_from_queue(struct sock *sk, struct sk_buff *__skb_try_recv_from_queue(struct sock *sk,
struct sk_buff_head *queue, struct sk_buff_head *queue,
unsigned int flags, unsigned int flags,
void (*destructor)(struct sock *sk,
struct sk_buff *skb),
int *off, int *err, int *off, int *err,
struct sk_buff **last); struct sk_buff **last);
struct sk_buff *__skb_try_recv_datagram(struct sock *sk, struct sk_buff *__skb_try_recv_datagram(struct sock *sk,
struct sk_buff_head *queue, struct sk_buff_head *queue,
unsigned int flags, unsigned int flags, int *off, int *err,
void (*destructor)(struct sock *sk,
struct sk_buff *skb),
int *off, int *err,
struct sk_buff **last); struct sk_buff **last);
struct sk_buff *__skb_recv_datagram(struct sock *sk, struct sk_buff *__skb_recv_datagram(struct sock *sk,
struct sk_buff_head *sk_queue, struct sk_buff_head *sk_queue,
unsigned int flags, unsigned int flags, int *off, int *err);
void (*destructor)(struct sock *sk,
struct sk_buff *skb),
int *off, int *err);
struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags, int noblock, struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags, int noblock,
int *err); int *err);
__poll_t datagram_poll(struct file *file, struct socket *sock, __poll_t datagram_poll(struct file *file, struct socket *sock,
......
...@@ -166,8 +166,6 @@ static struct sk_buff *skb_set_peeked(struct sk_buff *skb) ...@@ -166,8 +166,6 @@ static struct sk_buff *skb_set_peeked(struct sk_buff *skb)
struct sk_buff *__skb_try_recv_from_queue(struct sock *sk, struct sk_buff *__skb_try_recv_from_queue(struct sock *sk,
struct sk_buff_head *queue, struct sk_buff_head *queue,
unsigned int flags, unsigned int flags,
void (*destructor)(struct sock *sk,
struct sk_buff *skb),
int *off, int *err, int *off, int *err,
struct sk_buff **last) struct sk_buff **last)
{ {
...@@ -198,8 +196,6 @@ struct sk_buff *__skb_try_recv_from_queue(struct sock *sk, ...@@ -198,8 +196,6 @@ struct sk_buff *__skb_try_recv_from_queue(struct sock *sk,
refcount_inc(&skb->users); refcount_inc(&skb->users);
} else { } else {
__skb_unlink(skb, queue); __skb_unlink(skb, queue);
if (destructor)
destructor(sk, skb);
} }
*off = _off; *off = _off;
return skb; return skb;
...@@ -212,7 +208,6 @@ struct sk_buff *__skb_try_recv_from_queue(struct sock *sk, ...@@ -212,7 +208,6 @@ struct sk_buff *__skb_try_recv_from_queue(struct sock *sk,
* @sk: socket * @sk: socket
* @queue: socket queue from which to receive * @queue: socket queue from which to receive
* @flags: MSG\_ flags * @flags: MSG\_ flags
* @destructor: invoked under the receive lock on successful dequeue
* @off: an offset in bytes to peek skb from. Returns an offset * @off: an offset in bytes to peek skb from. Returns an offset
* within an skb where data actually starts * within an skb where data actually starts
* @err: error code returned * @err: error code returned
...@@ -245,10 +240,7 @@ struct sk_buff *__skb_try_recv_from_queue(struct sock *sk, ...@@ -245,10 +240,7 @@ struct sk_buff *__skb_try_recv_from_queue(struct sock *sk,
*/ */
struct sk_buff *__skb_try_recv_datagram(struct sock *sk, struct sk_buff *__skb_try_recv_datagram(struct sock *sk,
struct sk_buff_head *queue, struct sk_buff_head *queue,
unsigned int flags, unsigned int flags, int *off, int *err,
void (*destructor)(struct sock *sk,
struct sk_buff *skb),
int *off, int *err,
struct sk_buff **last) struct sk_buff **last)
{ {
struct sk_buff *skb; struct sk_buff *skb;
...@@ -269,8 +261,8 @@ struct sk_buff *__skb_try_recv_datagram(struct sock *sk, ...@@ -269,8 +261,8 @@ struct sk_buff *__skb_try_recv_datagram(struct sock *sk,
* However, this function was correct in any case. 8) * However, this function was correct in any case. 8)
*/ */
spin_lock_irqsave(&queue->lock, cpu_flags); spin_lock_irqsave(&queue->lock, cpu_flags);
skb = __skb_try_recv_from_queue(sk, queue, flags, destructor, skb = __skb_try_recv_from_queue(sk, queue, flags, off, &error,
off, &error, last); last);
spin_unlock_irqrestore(&queue->lock, cpu_flags); spin_unlock_irqrestore(&queue->lock, cpu_flags);
if (error) if (error)
goto no_packet; goto no_packet;
...@@ -293,10 +285,7 @@ EXPORT_SYMBOL(__skb_try_recv_datagram); ...@@ -293,10 +285,7 @@ EXPORT_SYMBOL(__skb_try_recv_datagram);
struct sk_buff *__skb_recv_datagram(struct sock *sk, struct sk_buff *__skb_recv_datagram(struct sock *sk,
struct sk_buff_head *sk_queue, struct sk_buff_head *sk_queue,
unsigned int flags, unsigned int flags, int *off, int *err)
void (*destructor)(struct sock *sk,
struct sk_buff *skb),
int *off, int *err)
{ {
struct sk_buff *skb, *last; struct sk_buff *skb, *last;
long timeo; long timeo;
...@@ -304,8 +293,8 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, ...@@ -304,8 +293,8 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk,
timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
do { do {
skb = __skb_try_recv_datagram(sk, sk_queue, flags, destructor, skb = __skb_try_recv_datagram(sk, sk_queue, flags, off, err,
off, err, &last); &last);
if (skb) if (skb)
return skb; return skb;
...@@ -326,7 +315,7 @@ struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned int flags, ...@@ -326,7 +315,7 @@ struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned int flags,
return __skb_recv_datagram(sk, &sk->sk_receive_queue, return __skb_recv_datagram(sk, &sk->sk_receive_queue,
flags | (noblock ? MSG_DONTWAIT : 0), flags | (noblock ? MSG_DONTWAIT : 0),
NULL, &off, err); &off, err);
} }
EXPORT_SYMBOL(skb_recv_datagram); EXPORT_SYMBOL(skb_recv_datagram);
......
...@@ -1671,10 +1671,11 @@ struct sk_buff *__skb_recv_udp(struct sock *sk, unsigned int flags, ...@@ -1671,10 +1671,11 @@ struct sk_buff *__skb_recv_udp(struct sock *sk, unsigned int flags,
error = -EAGAIN; error = -EAGAIN;
do { do {
spin_lock_bh(&queue->lock); spin_lock_bh(&queue->lock);
skb = __skb_try_recv_from_queue(sk, queue, flags, skb = __skb_try_recv_from_queue(sk, queue, flags, off,
udp_skb_destructor, err, &last);
off, err, &last);
if (skb) { if (skb) {
if (!(flags & MSG_PEEK))
udp_skb_destructor(sk, skb);
spin_unlock_bh(&queue->lock); spin_unlock_bh(&queue->lock);
return skb; return skb;
} }
...@@ -1692,9 +1693,10 @@ struct sk_buff *__skb_recv_udp(struct sock *sk, unsigned int flags, ...@@ -1692,9 +1693,10 @@ struct sk_buff *__skb_recv_udp(struct sock *sk, unsigned int flags,
spin_lock(&sk_queue->lock); spin_lock(&sk_queue->lock);
skb_queue_splice_tail_init(sk_queue, queue); skb_queue_splice_tail_init(sk_queue, queue);
skb = __skb_try_recv_from_queue(sk, queue, flags, skb = __skb_try_recv_from_queue(sk, queue, flags, off,
udp_skb_dtor_locked, err, &last);
off, err, &last); if (skb && !(flags & MSG_PEEK))
udp_skb_dtor_locked(sk, skb);
spin_unlock(&sk_queue->lock); spin_unlock(&sk_queue->lock);
spin_unlock_bh(&queue->lock); spin_unlock_bh(&queue->lock);
if (skb) if (skb)
......
...@@ -2106,9 +2106,12 @@ static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg, ...@@ -2106,9 +2106,12 @@ static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg,
skip = sk_peek_offset(sk, flags); skip = sk_peek_offset(sk, flags);
skb = __skb_try_recv_datagram(sk, &sk->sk_receive_queue, flags, skb = __skb_try_recv_datagram(sk, &sk->sk_receive_queue, flags,
scm_stat_del, &skip, &err, &last); &skip, &err, &last);
if (skb) if (skb) {
if (!(flags & MSG_PEEK))
scm_stat_del(sk, skb);
break; break;
}
mutex_unlock(&u->iolock); mutex_unlock(&u->iolock);
......
...@@ -100,7 +100,7 @@ static int espintcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, ...@@ -100,7 +100,7 @@ static int espintcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
flags |= nonblock ? MSG_DONTWAIT : 0; flags |= nonblock ? MSG_DONTWAIT : 0;
skb = __skb_recv_datagram(sk, &ctx->ike_queue, flags, NULL, &off, &err); skb = __skb_recv_datagram(sk, &ctx->ike_queue, flags, &off, &err);
if (!skb) if (!skb)
return err; return err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment