Skip to content

Commit 5a9e6cc

Browse files
SantoshShilimkargerd-rausch
authored andcommitted
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 Signed-off-by: Santosh Shilimkar <[email protected]> Reviewed-by: Shamir Rabinovitch <[email protected]> Acked-by: Ajaykumar Hotchandani <[email protected]> Acked-by: Sowmini Varadhan <[email protected]> Tested-by: Namrata Jampani <[email protected]> Orabug: 27364391 (cherry picked from commit d2cf302) cherry-pick-repo=linux-uek.git Signed-off-by: Gerd Rausch <[email protected]> Signed-off-by: Somasundaram Krishnasamy <[email protected]>
1 parent 53a472c commit 5a9e6cc

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
@@ -285,6 +285,7 @@ struct rds_incoming {
285285
struct sk_buff *i_skb;
286286

287287
rds_rdma_cookie_t i_rdma_cookie;
288+
struct timeval i_rx_tstamp;
288289
};
289290

290291
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

@@ -550,6 +554,8 @@ rds_recv_local(struct rds_connection *conn, __be32 saddr, __be32 daddr,
550554
rds_recv_rcvbuf_delta(rs, sk, inc->i_conn->c_lcong,
551555
be32_to_cpu(inc->i_hdr.h_len),
552556
inc->i_hdr.h_dport);
557+
if (sock_flag(sk, SOCK_RCVTSTAMP))
558+
do_gettimeofday(&inc->i_rx_tstamp);
553559
rds_inc_addref(inc);
554560
list_add_tail(&inc->i_item, &rs->rs_recv_queue);
555561
__rds_wake_sk_sleep(sk);
@@ -715,7 +721,8 @@ static int rds_notify_cong(struct rds_sock *rs, struct msghdr *msghdr)
715721
/*
716722
* Receive any control messages.
717723
*/
718-
static int rds_cmsg_recv(struct rds_incoming *inc, struct msghdr *msg)
724+
static int rds_cmsg_recv(struct rds_incoming *inc, struct msghdr *msg,
725+
struct rds_sock *rs)
719726
{
720727
int ret = 0;
721728

@@ -726,6 +733,15 @@ static int rds_cmsg_recv(struct rds_incoming *inc, struct msghdr *msg)
726733
return ret;
727734
}
728735

736+
if ((inc->i_rx_tstamp.tv_sec != 0) &&
737+
sock_flag(rds_rs_to_sk(rs), SOCK_RCVTSTAMP)) {
738+
ret = put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMP,
739+
sizeof(struct timeval),
740+
&inc->i_rx_tstamp);
741+
if (ret)
742+
return ret;
743+
}
744+
729745
return 0;
730746
}
731747

@@ -811,7 +827,7 @@ int rds_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
811827
msg->msg_flags |= MSG_TRUNC;
812828
}
813829

814-
if (rds_cmsg_recv(inc, msg)) {
830+
if (rds_cmsg_recv(inc, msg, rs)) {
815831
ret = -EFAULT;
816832
goto out;
817833
}

0 commit comments

Comments
 (0)