Advertisement
Guest User

Untitled

a guest
Aug 24th, 2015
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.80 KB | None | 0 0
  1. From 0474c4609c9387a3328ca03d34030e9724e437eb Mon Sep 17 00:00:00 2001
  2. From: Eric Dumazet <eric.dumazet@gmail.com>
  3. Date: Mon, 19 Sep 2011 05:52:27 +0000
  4. Subject: [PATCH 1/2] af_unix: dont send SCM_CREDENTIALS by default
  5.  
  6. Since commit 7361c36c5224 (af_unix: Allow credentials to work across
  7. user and pid namespaces) af_unix performance dropped a lot.
  8.  
  9. This is because we now take a reference on pid and cred in each write(),
  10. and release them in read(), usually done from another process,
  11. eventually from another cpu. This triggers false sharing.
  12.  
  13. # Events: 154K cycles
  14. #
  15. # Overhead Command Shared Object Symbol
  16. # ........ ....... .................. .........................
  17. #
  18. 10.40% hackbench [kernel.kallsyms] [k] put_pid
  19. 8.60% hackbench [kernel.kallsyms] [k] unix_stream_recvmsg
  20. 7.87% hackbench [kernel.kallsyms] [k] unix_stream_sendmsg
  21. 6.11% hackbench [kernel.kallsyms] [k] do_raw_spin_lock
  22. 4.95% hackbench [kernel.kallsyms] [k] unix_scm_to_skb
  23. 4.87% hackbench [kernel.kallsyms] [k] pid_nr_ns
  24. 4.34% hackbench [kernel.kallsyms] [k] cred_to_ucred
  25. 2.39% hackbench [kernel.kallsyms] [k] unix_destruct_scm
  26. 2.24% hackbench [kernel.kallsyms] [k] sub_preempt_count
  27. 1.75% hackbench [kernel.kallsyms] [k] fget_light
  28. 1.51% hackbench [kernel.kallsyms] [k]
  29. __mutex_lock_interruptible_slowpath
  30. 1.42% hackbench [kernel.kallsyms] [k] sock_alloc_send_pskb
  31.  
  32. This patch includes SCM_CREDENTIALS information in a af_unix message/skb
  33. only if requested by the sender, [man 7 unix for details how to include
  34. ancillary data using sendmsg() system call]
  35.  
  36. Note: This might break buggy applications that expected SCM_CREDENTIAL
  37. from an unaware write() system call, and receiver not using SO_PASSCRED
  38. socket option.
  39.  
  40. If SOCK_PASSCRED is set on source or destination socket, we still
  41. include credentials for mere write() syscalls.
  42.  
  43. Performance boost in hackbench : more than 50% gain on a 16 thread
  44. machine (2 quad-core cpus, 2 threads per core)
  45.  
  46. hackbench 20 thread 2000
  47.  
  48. 4.228 sec instead of 9.102 sec
  49.  
  50. Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
  51. Acked-by: Tim Chen <tim.c.chen@linux.intel.com>
  52. Signed-off-by: David S. Miller <davem@davemloft.net>
  53. ---
  54. include/net/scm.h | 5 ++---
  55. net/core/scm.c | 10 ++++++----
  56. net/netlink/af_netlink.c | 5 ++---
  57. net/unix/af_unix.c | 24 +++++++++++++++++++++++-
  58. 4 files changed, 33 insertions(+), 11 deletions(-)
  59.  
  60. diff --git a/include/net/scm.h b/include/net/scm.h
  61. index 745460f..d456f4c 100644
  62. --- a/include/net/scm.h
  63. +++ b/include/net/scm.h
  64. @@ -49,7 +49,7 @@ static __inline__ void scm_set_cred(struct scm_cookie *scm,
  65. struct pid *pid, const struct cred *cred)
  66. {
  67. scm->pid = get_pid(pid);
  68. - scm->cred = get_cred(cred);
  69. + scm->cred = cred ? get_cred(cred) : NULL;
  70. cred_to_ucred(pid, cred, &scm->creds);
  71. }
  72.  
  73. @@ -73,8 +73,7 @@ static __inline__ void scm_destroy(struct scm_cookie *scm)
  74. static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
  75. struct scm_cookie *scm)
  76. {
  77. - scm_set_cred(scm, task_tgid(current), current_cred());
  78. - scm->fp = NULL;
  79. + memset(scm, 0, sizeof(*scm));
  80. unix_get_peersec_dgram(sock, scm);
  81. if (msg->msg_controllen <= 0)
  82. return 0;
  83. diff --git a/net/core/scm.c b/net/core/scm.c
  84. index 811b53f..ff52ad0 100644
  85. --- a/net/core/scm.c
  86. +++ b/net/core/scm.c
  87. @@ -173,7 +173,7 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p)
  88. if (err)
  89. goto error;
  90.  
  91. - if (pid_vnr(p->pid) != p->creds.pid) {
  92. + if (!p->pid || pid_vnr(p->pid) != p->creds.pid) {
  93. struct pid *pid;
  94. err = -ESRCH;
  95. pid = find_get_pid(p->creds.pid);
  96. @@ -183,8 +183,9 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p)
  97. p->pid = pid;
  98. }
  99.  
  100. - if ((p->cred->euid != p->creds.uid) ||
  101. - (p->cred->egid != p->creds.gid)) {
  102. + if (!p->cred ||
  103. + (p->cred->euid != p->creds.uid) ||
  104. + (p->cred->egid != p->creds.gid)) {
  105. struct cred *cred;
  106. err = -ENOMEM;
  107. cred = prepare_creds();
  108. @@ -193,7 +194,8 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p)
  109.  
  110. cred->uid = cred->euid = p->creds.uid;
  111. cred->gid = cred->egid = p->creds.gid;
  112. - put_cred(p->cred);
  113. + if (p->cred)
  114. + put_cred(p->cred);
  115. p->cred = cred;
  116. }
  117. break;
  118. diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
  119. index 6ef64ad..ca2fead 100644
  120. --- a/net/netlink/af_netlink.c
  121. +++ b/net/netlink/af_netlink.c
  122. @@ -1324,10 +1324,9 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
  123. if (msg->msg_flags&MSG_OOB)
  124. return -EOPNOTSUPP;
  125.  
  126. - if (NULL == siocb->scm) {
  127. + if (NULL == siocb->scm)
  128. siocb->scm = &scm;
  129. - memset(&scm, 0, sizeof(scm));
  130. - }
  131. +
  132. err = scm_send(sock, msg, siocb->scm);
  133. if (err < 0)
  134. return err;
  135. diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
  136. index 0722a25..bb427ed 100644
  137. --- a/net/unix/af_unix.c
  138. +++ b/net/unix/af_unix.c
  139. @@ -1385,8 +1385,10 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
  140. static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds)
  141. {
  142. int err = 0;
  143. +
  144. UNIXCB(skb).pid = get_pid(scm->pid);
  145. - UNIXCB(skb).cred = get_cred(scm->cred);
  146. + if (scm->cred)
  147. + UNIXCB(skb).cred = get_cred(scm->cred);
  148. UNIXCB(skb).fp = NULL;
  149. if (scm->fp && send_fds)
  150. err = unix_attach_fds(scm, skb);
  151. @@ -1396,6 +1398,24 @@ static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool sen
  152. }
  153.  
  154. /*
  155. + * Some apps rely on write() giving SCM_CREDENTIALS
  156. + * We include credentials if source or destination socket
  157. + * asserted SOCK_PASSCRED.
  158. + */
  159. +static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock,
  160. + const struct sock *other)
  161. +{
  162. + if (UNIXCB(skb).cred)
  163. + return;
  164. + if (test_bit(SOCK_PASSCRED, &sock->flags) ||
  165. + !other->sk_socket ||
  166. + test_bit(SOCK_PASSCRED, &other->sk_socket->flags)) {
  167. + UNIXCB(skb).pid = get_pid(task_tgid(current));
  168. + UNIXCB(skb).cred = get_current_cred();
  169. + }
  170. +}
  171. +
  172. +/*
  173. * Send AF_UNIX data.
  174. */
  175.  
  176. @@ -1542,6 +1562,7 @@ restart:
  177.  
  178. if (sock_flag(other, SOCK_RCVTSTAMP))
  179. __net_timestamp(skb);
  180. + maybe_add_creds(skb, sock, other);
  181. skb_queue_tail(&other->sk_receive_queue, skb);
  182. if (max_level > unix_sk(other)->recursion_level)
  183. unix_sk(other)->recursion_level = max_level;
  184. @@ -1656,6 +1677,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
  185. (other->sk_shutdown & RCV_SHUTDOWN))
  186. goto pipe_err_free;
  187.  
  188. + maybe_add_creds(skb, sock, other);
  189. skb_queue_tail(&other->sk_receive_queue, skb);
  190. if (max_level > unix_sk(other)->recursion_level)
  191. unix_sk(other)->recursion_level = max_level;
  192. --
  193. 1.7.7.6
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement