diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-16 18:25:31 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-16 18:25:31 -0500 |
| commit | 0b233b7c79d2ba92c7fb5d60d4116693f1b3b0fe (patch) | |
| tree | 440a6093bacfadf46782592fff22c4a2b2b51443 /include | |
| parent | 6f51ee709e4c6b56f2c2a071da2d056a109b9d26 (diff) | |
| parent | bf7491f1be5e125eece2ec67e0f79d513caa6c7e (diff) | |
Merge branch 'for-3.19' of git://linux-nfs.org/~bfields/linux
Pull nfsd updates from Bruce Fields:
"A comparatively quieter cycle for nfsd this time, but still with two
larger changes:
- RPC server scalability improvements from Jeff Layton (using RCU
instead of a spinlock to find idle threads).
- server-side NFSv4.2 ALLOCATE/DEALLOCATE support from Anna
Schumaker, enabling fallocate on new clients"
* 'for-3.19' of git://linux-nfs.org/~bfields/linux: (32 commits)
nfsd4: fix xdr4 count of server in fs_location4
nfsd4: fix xdr4 inclusion of escaped char
sunrpc/cache: convert to use string_escape_str()
sunrpc: only call test_bit once in svc_xprt_received
fs: nfsd: Fix signedness bug in compare_blob
sunrpc: add some tracepoints around enqueue and dequeue of svc_xprt
sunrpc: convert to lockless lookup of queued server threads
sunrpc: fix potential races in pool_stats collection
sunrpc: add a rcu_head to svc_rqst and use kfree_rcu to free it
sunrpc: require svc_create callers to pass in meaningful shutdown routine
sunrpc: have svc_wake_up only deal with pool 0
sunrpc: convert sp_task_pending flag to use atomic bitops
sunrpc: move rq_cachetype field to better optimize space
sunrpc: move rq_splice_ok flag into rq_flags
sunrpc: move rq_dropme flag into rq_flags
sunrpc: move rq_usedeferral flag to rq_flags
sunrpc: move rq_local field to rq_flags
sunrpc: add a generic rq_flags field to svc_rqst and move rq_secure to it
nfsd: minor off by one checks in __write_versions()
sunrpc: release svc_pool_map reference when serv allocation fails
...
Diffstat (limited to 'include')
| -rw-r--r-- | include/linux/fs.h | 2 | ||||
| -rw-r--r-- | include/linux/sunrpc/svc.h | 34 | ||||
| -rw-r--r-- | include/linux/sunrpc/svc_xprt.h | 7 | ||||
| -rw-r--r-- | include/trace/events/sunrpc.h | 120 |
4 files changed, 137 insertions, 26 deletions
diff --git a/include/linux/fs.h b/include/linux/fs.h index 88157253b9e6..eeaccd37184f 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
| @@ -2086,7 +2086,7 @@ struct filename { | |||
| 2086 | extern long vfs_truncate(struct path *, loff_t); | 2086 | extern long vfs_truncate(struct path *, loff_t); |
| 2087 | extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs, | 2087 | extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs, |
| 2088 | struct file *filp); | 2088 | struct file *filp); |
| 2089 | extern int do_fallocate(struct file *file, int mode, loff_t offset, | 2089 | extern int vfs_fallocate(struct file *file, int mode, loff_t offset, |
| 2090 | loff_t len); | 2090 | loff_t len); |
| 2091 | extern long do_sys_open(int dfd, const char __user *filename, int flags, | 2091 | extern long do_sys_open(int dfd, const char __user *filename, int flags, |
| 2092 | umode_t mode); | 2092 | umode_t mode); |
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index 21678464883a..6f22cfeef5e3 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h | |||
| @@ -26,10 +26,10 @@ typedef int (*svc_thread_fn)(void *); | |||
| 26 | 26 | ||
| 27 | /* statistics for svc_pool structures */ | 27 | /* statistics for svc_pool structures */ |
| 28 | struct svc_pool_stats { | 28 | struct svc_pool_stats { |
| 29 | unsigned long packets; | 29 | atomic_long_t packets; |
| 30 | unsigned long sockets_queued; | 30 | unsigned long sockets_queued; |
| 31 | unsigned long threads_woken; | 31 | atomic_long_t threads_woken; |
| 32 | unsigned long threads_timedout; | 32 | atomic_long_t threads_timedout; |
| 33 | }; | 33 | }; |
| 34 | 34 | ||
| 35 | /* | 35 | /* |
| @@ -45,12 +45,13 @@ struct svc_pool_stats { | |||
| 45 | struct svc_pool { | 45 | struct svc_pool { |
| 46 | unsigned int sp_id; /* pool id; also node id on NUMA */ | 46 | unsigned int sp_id; /* pool id; also node id on NUMA */ |
| 47 | spinlock_t sp_lock; /* protects all fields */ | 47 | spinlock_t sp_lock; /* protects all fields */ |
| 48 | struct list_head sp_threads; /* idle server threads */ | ||
| 49 | struct list_head sp_sockets; /* pending sockets */ | 48 | struct list_head sp_sockets; /* pending sockets */ |
| 50 | unsigned int sp_nrthreads; /* # of threads in pool */ | 49 | unsigned int sp_nrthreads; /* # of threads in pool */ |
| 51 | struct list_head sp_all_threads; /* all server threads */ | 50 | struct list_head sp_all_threads; /* all server threads */ |
| 52 | struct svc_pool_stats sp_stats; /* statistics on pool operation */ | 51 | struct svc_pool_stats sp_stats; /* statistics on pool operation */ |
| 53 | int sp_task_pending;/* has pending task */ | 52 | #define SP_TASK_PENDING (0) /* still work to do even if no |
| 53 | * xprt is queued. */ | ||
| 54 | unsigned long sp_flags; | ||
| 54 | } ____cacheline_aligned_in_smp; | 55 | } ____cacheline_aligned_in_smp; |
| 55 | 56 | ||
| 56 | /* | 57 | /* |
| @@ -219,8 +220,8 @@ static inline void svc_putu32(struct kvec *iov, __be32 val) | |||
| 219 | * processed. | 220 | * processed. |
| 220 | */ | 221 | */ |
| 221 | struct svc_rqst { | 222 | struct svc_rqst { |
| 222 | struct list_head rq_list; /* idle list */ | ||
| 223 | struct list_head rq_all; /* all threads list */ | 223 | struct list_head rq_all; /* all threads list */ |
| 224 | struct rcu_head rq_rcu_head; /* for RCU deferred kfree */ | ||
| 224 | struct svc_xprt * rq_xprt; /* transport ptr */ | 225 | struct svc_xprt * rq_xprt; /* transport ptr */ |
| 225 | 226 | ||
| 226 | struct sockaddr_storage rq_addr; /* peer address */ | 227 | struct sockaddr_storage rq_addr; /* peer address */ |
| @@ -236,7 +237,6 @@ struct svc_rqst { | |||
| 236 | struct svc_cred rq_cred; /* auth info */ | 237 | struct svc_cred rq_cred; /* auth info */ |
| 237 | void * rq_xprt_ctxt; /* transport specific context ptr */ | 238 | void * rq_xprt_ctxt; /* transport specific context ptr */ |
| 238 | struct svc_deferred_req*rq_deferred; /* deferred request we are replaying */ | 239 | struct svc_deferred_req*rq_deferred; /* deferred request we are replaying */ |
| 239 | bool rq_usedeferral; /* use deferral */ | ||
| 240 | 240 | ||
| 241 | size_t rq_xprt_hlen; /* xprt header len */ | 241 | size_t rq_xprt_hlen; /* xprt header len */ |
| 242 | struct xdr_buf rq_arg; | 242 | struct xdr_buf rq_arg; |
| @@ -253,9 +253,17 @@ struct svc_rqst { | |||
| 253 | u32 rq_vers; /* program version */ | 253 | u32 rq_vers; /* program version */ |
| 254 | u32 rq_proc; /* procedure number */ | 254 | u32 rq_proc; /* procedure number */ |
| 255 | u32 rq_prot; /* IP protocol */ | 255 | u32 rq_prot; /* IP protocol */ |
| 256 | unsigned short | 256 | int rq_cachetype; /* catering to nfsd */ |
| 257 | rq_secure : 1; /* secure port */ | 257 | #define RQ_SECURE (0) /* secure port */ |
| 258 | unsigned short rq_local : 1; /* local request */ | 258 | #define RQ_LOCAL (1) /* local request */ |
| 259 | #define RQ_USEDEFERRAL (2) /* use deferral */ | ||
| 260 | #define RQ_DROPME (3) /* drop current reply */ | ||
| 261 | #define RQ_SPLICE_OK (4) /* turned off in gss privacy | ||
| 262 | * to prevent encrypting page | ||
| 263 | * cache pages */ | ||
| 264 | #define RQ_VICTIM (5) /* about to be shut down */ | ||
| 265 | #define RQ_BUSY (6) /* request is busy */ | ||
| 266 | unsigned long rq_flags; /* flags field */ | ||
| 259 | 267 | ||
| 260 | void * rq_argp; /* decoded arguments */ | 268 | void * rq_argp; /* decoded arguments */ |
| 261 | void * rq_resp; /* xdr'd results */ | 269 | void * rq_resp; /* xdr'd results */ |
| @@ -271,16 +279,12 @@ struct svc_rqst { | |||
| 271 | struct cache_req rq_chandle; /* handle passed to caches for | 279 | struct cache_req rq_chandle; /* handle passed to caches for |
| 272 | * request delaying | 280 | * request delaying |
| 273 | */ | 281 | */ |
| 274 | bool rq_dropme; | ||
| 275 | /* Catering to nfsd */ | 282 | /* Catering to nfsd */ |
| 276 | struct auth_domain * rq_client; /* RPC peer info */ | 283 | struct auth_domain * rq_client; /* RPC peer info */ |
| 277 | struct auth_domain * rq_gssclient; /* "gss/"-style peer info */ | 284 | struct auth_domain * rq_gssclient; /* "gss/"-style peer info */ |
| 278 | int rq_cachetype; | ||
| 279 | struct svc_cacherep * rq_cacherep; /* cache info */ | 285 | struct svc_cacherep * rq_cacherep; /* cache info */ |
| 280 | bool rq_splice_ok; /* turned off in gss privacy | ||
| 281 | * to prevent encrypting page | ||
| 282 | * cache pages */ | ||
| 283 | struct task_struct *rq_task; /* service thread */ | 286 | struct task_struct *rq_task; /* service thread */ |
| 287 | spinlock_t rq_lock; /* per-request lock */ | ||
| 284 | }; | 288 | }; |
| 285 | 289 | ||
| 286 | #define SVC_NET(svc_rqst) (svc_rqst->rq_xprt->xpt_net) | 290 | #define SVC_NET(svc_rqst) (svc_rqst->rq_xprt->xpt_net) |
diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h index ce6e4182a5b2..79f6f8f3dc0a 100644 --- a/include/linux/sunrpc/svc_xprt.h +++ b/include/linux/sunrpc/svc_xprt.h | |||
| @@ -63,10 +63,9 @@ struct svc_xprt { | |||
| 63 | #define XPT_CHNGBUF 7 /* need to change snd/rcv buf sizes */ | 63 | #define XPT_CHNGBUF 7 /* need to change snd/rcv buf sizes */ |
| 64 | #define XPT_DEFERRED 8 /* deferred request pending */ | 64 | #define XPT_DEFERRED 8 /* deferred request pending */ |
| 65 | #define XPT_OLD 9 /* used for xprt aging mark+sweep */ | 65 | #define XPT_OLD 9 /* used for xprt aging mark+sweep */ |
| 66 | #define XPT_DETACHED 10 /* detached from tempsocks list */ | 66 | #define XPT_LISTENER 10 /* listening endpoint */ |
| 67 | #define XPT_LISTENER 11 /* listening endpoint */ | 67 | #define XPT_CACHE_AUTH 11 /* cache auth info */ |
| 68 | #define XPT_CACHE_AUTH 12 /* cache auth info */ | 68 | #define XPT_LOCAL 12 /* connection from loopback interface */ |
| 69 | #define XPT_LOCAL 13 /* connection from loopback interface */ | ||
| 70 | 69 | ||
| 71 | struct svc_serv *xpt_server; /* service for transport */ | 70 | struct svc_serv *xpt_server; /* service for transport */ |
| 72 | atomic_t xpt_reserved; /* space on outq that is rsvd */ | 71 | atomic_t xpt_reserved; /* space on outq that is rsvd */ |
diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h index 171ca4ff6d99..b9c1dc6c825a 100644 --- a/include/trace/events/sunrpc.h +++ b/include/trace/events/sunrpc.h | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #include <linux/sunrpc/clnt.h> | 8 | #include <linux/sunrpc/clnt.h> |
| 9 | #include <linux/sunrpc/svc.h> | 9 | #include <linux/sunrpc/svc.h> |
| 10 | #include <linux/sunrpc/xprtsock.h> | 10 | #include <linux/sunrpc/xprtsock.h> |
| 11 | #include <linux/sunrpc/svc_xprt.h> | ||
| 11 | #include <net/tcp_states.h> | 12 | #include <net/tcp_states.h> |
| 12 | #include <linux/net.h> | 13 | #include <linux/net.h> |
| 13 | #include <linux/tracepoint.h> | 14 | #include <linux/tracepoint.h> |
| @@ -412,6 +413,16 @@ TRACE_EVENT(xs_tcp_data_recv, | |||
| 412 | __entry->copied, __entry->reclen, __entry->offset) | 413 | __entry->copied, __entry->reclen, __entry->offset) |
| 413 | ); | 414 | ); |
| 414 | 415 | ||
| 416 | #define show_rqstp_flags(flags) \ | ||
| 417 | __print_flags(flags, "|", \ | ||
| 418 | { (1UL << RQ_SECURE), "RQ_SECURE"}, \ | ||
| 419 | { (1UL << RQ_LOCAL), "RQ_LOCAL"}, \ | ||
| 420 | { (1UL << RQ_USEDEFERRAL), "RQ_USEDEFERRAL"}, \ | ||
| 421 | { (1UL << RQ_DROPME), "RQ_DROPME"}, \ | ||
| 422 | { (1UL << RQ_SPLICE_OK), "RQ_SPLICE_OK"}, \ | ||
| 423 | { (1UL << RQ_VICTIM), "RQ_VICTIM"}, \ | ||
| 424 | { (1UL << RQ_BUSY), "RQ_BUSY"}) | ||
| 425 | |||
| 415 | TRACE_EVENT(svc_recv, | 426 | TRACE_EVENT(svc_recv, |
| 416 | TP_PROTO(struct svc_rqst *rqst, int status), | 427 | TP_PROTO(struct svc_rqst *rqst, int status), |
| 417 | 428 | ||
| @@ -421,16 +432,19 @@ TRACE_EVENT(svc_recv, | |||
| 421 | __field(struct sockaddr *, addr) | 432 | __field(struct sockaddr *, addr) |
| 422 | __field(__be32, xid) | 433 | __field(__be32, xid) |
| 423 | __field(int, status) | 434 | __field(int, status) |
| 435 | __field(unsigned long, flags) | ||
| 424 | ), | 436 | ), |
| 425 | 437 | ||
| 426 | TP_fast_assign( | 438 | TP_fast_assign( |
| 427 | __entry->addr = (struct sockaddr *)&rqst->rq_addr; | 439 | __entry->addr = (struct sockaddr *)&rqst->rq_addr; |
| 428 | __entry->xid = status > 0 ? rqst->rq_xid : 0; | 440 | __entry->xid = status > 0 ? rqst->rq_xid : 0; |
| 429 | __entry->status = status; | 441 | __entry->status = status; |
| 442 | __entry->flags = rqst->rq_flags; | ||
| 430 | ), | 443 | ), |
| 431 | 444 | ||
| 432 | TP_printk("addr=%pIScp xid=0x%x status=%d", __entry->addr, | 445 | TP_printk("addr=%pIScp xid=0x%x status=%d flags=%s", __entry->addr, |
| 433 | be32_to_cpu(__entry->xid), __entry->status) | 446 | be32_to_cpu(__entry->xid), __entry->status, |
| 447 | show_rqstp_flags(__entry->flags)) | ||
| 434 | ); | 448 | ); |
| 435 | 449 | ||
| 436 | DECLARE_EVENT_CLASS(svc_rqst_status, | 450 | DECLARE_EVENT_CLASS(svc_rqst_status, |
| @@ -444,18 +458,19 @@ DECLARE_EVENT_CLASS(svc_rqst_status, | |||
| 444 | __field(__be32, xid) | 458 | __field(__be32, xid) |
| 445 | __field(int, dropme) | 459 | __field(int, dropme) |
| 446 | __field(int, status) | 460 | __field(int, status) |
| 461 | __field(unsigned long, flags) | ||
| 447 | ), | 462 | ), |
| 448 | 463 | ||
| 449 | TP_fast_assign( | 464 | TP_fast_assign( |
| 450 | __entry->addr = (struct sockaddr *)&rqst->rq_addr; | 465 | __entry->addr = (struct sockaddr *)&rqst->rq_addr; |
| 451 | __entry->xid = rqst->rq_xid; | 466 | __entry->xid = rqst->rq_xid; |
| 452 | __entry->dropme = (int)rqst->rq_dropme; | ||
| 453 | __entry->status = status; | 467 | __entry->status = status; |
| 468 | __entry->flags = rqst->rq_flags; | ||
| 454 | ), | 469 | ), |
| 455 | 470 | ||
| 456 | TP_printk("addr=%pIScp rq_xid=0x%x dropme=%d status=%d", | 471 | TP_printk("addr=%pIScp rq_xid=0x%x status=%d flags=%s", |
| 457 | __entry->addr, be32_to_cpu(__entry->xid), __entry->dropme, | 472 | __entry->addr, be32_to_cpu(__entry->xid), |
| 458 | __entry->status) | 473 | __entry->status, show_rqstp_flags(__entry->flags)) |
| 459 | ); | 474 | ); |
| 460 | 475 | ||
| 461 | DEFINE_EVENT(svc_rqst_status, svc_process, | 476 | DEFINE_EVENT(svc_rqst_status, svc_process, |
| @@ -466,6 +481,99 @@ DEFINE_EVENT(svc_rqst_status, svc_send, | |||
| 466 | TP_PROTO(struct svc_rqst *rqst, int status), | 481 | TP_PROTO(struct svc_rqst *rqst, int status), |
| 467 | TP_ARGS(rqst, status)); | 482 | TP_ARGS(rqst, status)); |
| 468 | 483 | ||
| 484 | #define show_svc_xprt_flags(flags) \ | ||
| 485 | __print_flags(flags, "|", \ | ||
| 486 | { (1UL << XPT_BUSY), "XPT_BUSY"}, \ | ||
| 487 | { (1UL << XPT_CONN), "XPT_CONN"}, \ | ||
| 488 | { (1UL << XPT_CLOSE), "XPT_CLOSE"}, \ | ||
| 489 | { (1UL << XPT_DATA), "XPT_DATA"}, \ | ||
| 490 | { (1UL << XPT_TEMP), "XPT_TEMP"}, \ | ||
| 491 | { (1UL << XPT_DEAD), "XPT_DEAD"}, \ | ||
| 492 | { (1UL << XPT_CHNGBUF), "XPT_CHNGBUF"}, \ | ||
| 493 | { (1UL << XPT_DEFERRED), "XPT_DEFERRED"}, \ | ||
| 494 | { (1UL << XPT_OLD), "XPT_OLD"}, \ | ||
| 495 | { (1UL << XPT_LISTENER), "XPT_LISTENER"}, \ | ||
| 496 | { (1UL << XPT_CACHE_AUTH), "XPT_CACHE_AUTH"}, \ | ||
| 497 | { (1UL << XPT_LOCAL), "XPT_LOCAL"}) | ||
| 498 | |||
| 499 | TRACE_EVENT(svc_xprt_do_enqueue, | ||
| 500 | TP_PROTO(struct svc_xprt *xprt, struct svc_rqst *rqst), | ||
| 501 | |||
| 502 | TP_ARGS(xprt, rqst), | ||
| 503 | |||
| 504 | TP_STRUCT__entry( | ||
| 505 | __field(struct svc_xprt *, xprt) | ||
| 506 | __field(struct svc_rqst *, rqst) | ||
| 507 | ), | ||
| 508 | |||
| 509 | TP_fast_assign( | ||
| 510 | __entry->xprt = xprt; | ||
| 511 | __entry->rqst = rqst; | ||
| 512 | ), | ||
| 513 | |||
| 514 | TP_printk("xprt=0x%p addr=%pIScp pid=%d flags=%s", __entry->xprt, | ||
| 515 | (struct sockaddr *)&__entry->xprt->xpt_remote, | ||
| 516 | __entry->rqst ? __entry->rqst->rq_task->pid : 0, | ||
| 517 | show_svc_xprt_flags(__entry->xprt->xpt_flags)) | ||
| 518 | ); | ||
| 519 | |||
| 520 | TRACE_EVENT(svc_xprt_dequeue, | ||
| 521 | TP_PROTO(struct svc_xprt *xprt), | ||
| 522 | |||
| 523 | TP_ARGS(xprt), | ||
| 524 | |||
| 525 | TP_STRUCT__entry( | ||
| 526 | __field(struct svc_xprt *, xprt) | ||
| 527 | __field_struct(struct sockaddr_storage, ss) | ||
| 528 | __field(unsigned long, flags) | ||
| 529 | ), | ||
| 530 | |||
| 531 | TP_fast_assign( | ||
| 532 | __entry->xprt = xprt, | ||
| 533 | xprt ? memcpy(&__entry->ss, &xprt->xpt_remote, sizeof(__entry->ss)) : memset(&__entry->ss, 0, sizeof(__entry->ss)); | ||
| 534 | __entry->flags = xprt ? xprt->xpt_flags : 0; | ||
| 535 | ), | ||
| 536 | |||
| 537 | TP_printk("xprt=0x%p addr=%pIScp flags=%s", __entry->xprt, | ||
| 538 | (struct sockaddr *)&__entry->ss, | ||
| 539 | show_svc_xprt_flags(__entry->flags)) | ||
| 540 | ); | ||
| 541 | |||
| 542 | TRACE_EVENT(svc_wake_up, | ||
| 543 | TP_PROTO(int pid), | ||
| 544 | |||
| 545 | TP_ARGS(pid), | ||
| 546 | |||
| 547 | TP_STRUCT__entry( | ||
| 548 | __field(int, pid) | ||
| 549 | ), | ||
| 550 | |||
| 551 | TP_fast_assign( | ||
| 552 | __entry->pid = pid; | ||
| 553 | ), | ||
| 554 | |||
| 555 | TP_printk("pid=%d", __entry->pid) | ||
| 556 | ); | ||
| 557 | |||
| 558 | TRACE_EVENT(svc_handle_xprt, | ||
| 559 | TP_PROTO(struct svc_xprt *xprt, int len), | ||
| 560 | |||
| 561 | TP_ARGS(xprt, len), | ||
| 562 | |||
| 563 | TP_STRUCT__entry( | ||
| 564 | __field(struct svc_xprt *, xprt) | ||
| 565 | __field(int, len) | ||
| 566 | ), | ||
| 567 | |||
| 568 | TP_fast_assign( | ||
| 569 | __entry->xprt = xprt; | ||
| 570 | __entry->len = len; | ||
| 571 | ), | ||
| 572 | |||
| 573 | TP_printk("xprt=0x%p addr=%pIScp len=%d flags=%s", __entry->xprt, | ||
| 574 | (struct sockaddr *)&__entry->xprt->xpt_remote, __entry->len, | ||
| 575 | show_svc_xprt_flags(__entry->xprt->xpt_flags)) | ||
| 576 | ); | ||
| 469 | #endif /* _TRACE_SUNRPC_H */ | 577 | #endif /* _TRACE_SUNRPC_H */ |
| 470 | 578 | ||
| 471 | #include <trace/define_trace.h> | 579 | #include <trace/define_trace.h> |
