Skip to content

Commit d2cf302

Browse files
RDS: Add support for per socket SO_TIMESTAMP for incoming messages
The SO_TIMESTAMP generates time stamp for each incoming RDS message using the wall time. Result is returned via recv_msg() in a control message as timeval (usec resolution). User app can enable it by using SO_TIMESTAMP setsocketopt() at SOL_SOCKET level. CMSG data of cmsg type SO_TIMESTAMP contains the time stamp in struct timeval format. Orabug: 22190837 Acked-by: Ajaykumar Hotchandani <[email protected]> Acked-by: Sowmini Varadhan <[email protected]> Reviewed-by: Shamir Rabinovitch <[email protected]> Tested-by: Namrata Jampani <[email protected]> Signed-off-by: Santosh Shilimkar <[email protected]>
1 parent 5631f1a commit d2cf302

File tree

3 files changed

+45
-2
lines changed

3 files changed

+45
-2
lines changed

net/rds/af_rds.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,27 @@ static int rds_set_transport(struct rds_sock *rs, char __user *optval,
362362
return rs->rs_transport ? 0 : -ENOPROTOOPT;
363363
}
364364

365+
static int rds_enable_recvtstamp(struct sock *sk, char __user *optval,
366+
int optlen)
367+
{
368+
int val, valbool;
369+
370+
if (optlen != sizeof(int))
371+
return -EFAULT;
372+
373+
if (get_user(val, (int __user *)optval))
374+
return -EFAULT;
375+
376+
valbool = val ? 1 : 0;
377+
378+
if (valbool)
379+
sock_set_flag(sk, SOCK_RCVTSTAMP);
380+
else
381+
sock_reset_flag(sk, SOCK_RCVTSTAMP);
382+
383+
return 0;
384+
}
385+
365386
static int rds_setsockopt(struct socket *sock, int level, int optname,
366387
char __user *optval, unsigned int optlen)
367388
{
@@ -400,6 +421,11 @@ static int rds_setsockopt(struct socket *sock, int level, int optname,
400421
ret = rds_set_transport(rs, optval, optlen);
401422
release_sock(sock->sk);
402423
break;
424+
case SO_TIMESTAMP:
425+
lock_sock(sock->sk);
426+
ret = rds_enable_recvtstamp(sock->sk, optval, optlen);
427+
release_sock(sock->sk);
428+
break;
403429
default:
404430
ret = -ENOPROTOOPT;
405431
}

net/rds/rds.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,7 @@ struct rds_incoming {
284284
struct sk_buff *i_skb;
285285

286286
rds_rdma_cookie_t i_rdma_cookie;
287+
struct timeval i_rx_tstamp;
287288
};
288289

289290
struct rds_mr {

net/rds/recv.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
#include <linux/in.h>
3636
#include <linux/ip.h>
3737
#include <linux/netfilter.h>
38+
#include <linux/time.h>
39+
#include <linux/rds.h>
3840

3941
#include "rds.h"
4042
#include "tcp.h"
@@ -73,6 +75,8 @@ void rds_inc_init(struct rds_incoming *inc, struct rds_connection *conn,
7375
inc->i_rdma_cookie = 0;
7476
inc->i_oconn = NULL;
7577
inc->i_skb = NULL;
78+
inc->i_rx_tstamp.tv_sec = 0;
79+
inc->i_rx_tstamp.tv_usec = 0;
7680
}
7781
EXPORT_SYMBOL_GPL(rds_inc_init);
7882

@@ -546,6 +550,8 @@ rds_recv_local(struct rds_connection *conn, __be32 saddr, __be32 daddr,
546550
rds_recv_rcvbuf_delta(rs, sk, inc->i_conn->c_lcong,
547551
be32_to_cpu(inc->i_hdr.h_len),
548552
inc->i_hdr.h_dport);
553+
if (sock_flag(sk, SOCK_RCVTSTAMP))
554+
do_gettimeofday(&inc->i_rx_tstamp);
549555
rds_inc_addref(inc);
550556
list_add_tail(&inc->i_item, &rs->rs_recv_queue);
551557
__rds_wake_sk_sleep(sk);
@@ -711,7 +717,8 @@ static int rds_notify_cong(struct rds_sock *rs, struct msghdr *msghdr)
711717
/*
712718
* Receive any control messages.
713719
*/
714-
static int rds_cmsg_recv(struct rds_incoming *inc, struct msghdr *msg)
720+
static int rds_cmsg_recv(struct rds_incoming *inc, struct msghdr *msg,
721+
struct rds_sock *rs)
715722
{
716723
int ret = 0;
717724

@@ -722,6 +729,15 @@ static int rds_cmsg_recv(struct rds_incoming *inc, struct msghdr *msg)
722729
return ret;
723730
}
724731

732+
if ((inc->i_rx_tstamp.tv_sec != 0) &&
733+
sock_flag(rds_rs_to_sk(rs), SOCK_RCVTSTAMP)) {
734+
ret = put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMP,
735+
sizeof(struct timeval),
736+
&inc->i_rx_tstamp);
737+
if (ret)
738+
return ret;
739+
}
740+
725741
return 0;
726742
}
727743

@@ -807,7 +823,7 @@ int rds_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
807823
msg->msg_flags |= MSG_TRUNC;
808824
}
809825

810-
if (rds_cmsg_recv(inc, msg)) {
826+
if (rds_cmsg_recv(inc, msg, rs)) {
811827
ret = -EFAULT;
812828
goto out;
813829
}

0 commit comments

Comments
 (0)