diff --git a/lustre/include/linux/obd.h b/lustre/include/linux/obd.h index 1a9071e87bb53c98cc9e1049ebaa104145a8ac3b..a6a7146ea650aeb5609f7781ec358d267a05c2db 100644 --- a/lustre/include/linux/obd.h +++ b/lustre/include/linux/obd.h @@ -360,12 +360,19 @@ struct client_obd { /* debug stuff */ struct timeval cl_last_write_time; - long cl_write_gap_sum; - long cl_write_gaps; - long cl_write_num; - long cl_read_num; - long cl_cache_wait_num; - long cl_cache_wait_sum; + unsigned long cl_write_gap_sum; + unsigned long cl_write_gaps; + unsigned long cl_write_num; + unsigned long cl_read_num; + unsigned long cl_cache_wait_num; + unsigned long cl_cache_wait_sum; + + unsigned long cl_dirty_num; + unsigned long cl_dirty_sum; + unsigned long cl_dirty_av; + + unsigned long cl_dirty_dmax; + unsigned long cl_dirty_dmin; }; /* Like a client, with some hangers-on. Keep mc_client_obd first so that we diff --git a/lustre/ldlm/ldlm_lib.c b/lustre/ldlm/ldlm_lib.c index 9fe909510c1a7f0fa67dd76a2e4f8719d2bedd55..c4f5f606421835c538e55c5421887a6a1f42e71c 100644 --- a/lustre/ldlm/ldlm_lib.c +++ b/lustre/ldlm/ldlm_lib.c @@ -256,6 +256,7 @@ int client_obd_setup(struct obd_device *obddev, obd_count len, void *buf) memset(&cli->cl_last_write_time, 0, sizeof(cli->cl_last_write_time)); + cli->cl_write_gap_sum = 0; cli->cl_write_gaps = 0; cli->cl_write_num = 0; @@ -263,6 +264,12 @@ int client_obd_setup(struct obd_device *obddev, obd_count len, void *buf) cli->cl_cache_wait_num = 0; cli->cl_cache_wait_sum = 0; + cli->cl_dirty_num = 0; + cli->cl_dirty_sum = 0; + cli->cl_dirty_av = 0; + cli->cl_dirty_dmax = 0; + cli->cl_dirty_dmin = 0; + if (num_physpages >> (20 - PAGE_SHIFT) <= 128) { /* <= 128 MB */ cli->cl_max_pages_per_rpc = PTLRPC_MAX_BRW_PAGES / 4; cli->cl_max_rpcs_in_flight = OSC_MAX_RIF_DEFAULT / 4; @@ -374,28 +381,40 @@ int client_obd_cleanup(struct obd_device *obddev, int flags) symbol_put("mgmtcli_deregister_for_events"); } - /* Here we try to drop the security structure after destroy import, - * to avoid issue of "sleep in spinlock". - */ - class_import_get(cli->cl_import); - class_destroy_import(cli->cl_import); - ptlrpcs_import_drop_sec(cli->cl_import); - class_import_put(cli->cl_import); - cli->cl_import = NULL; - if (cli->cl_write_gaps) { - CWARN("%s: (write num: %lu, read num: %lu): %lu write gaps: %lu " + CWARN("%s: [writes num: %lu, reads num: %lu]: %lu write gaps: %lu " "av. (usec), %lu total (usec)\n", obddev->obd_name, cli->cl_write_num, cli->cl_read_num, cli->cl_write_gaps, cli->cl_write_gap_sum / cli->cl_write_gaps, cli->cl_write_gap_sum); } + if (cli->cl_cache_wait_num) { - CWARN("%s: cache wait num: %lu, cache wait av. %lu (usec)\n", + CWARN("%s: [cache waits num: %lu]: cache wait av. %lu (usec)\n", obddev->obd_name, cli->cl_cache_wait_num, cli->cl_cache_wait_sum / cli->cl_cache_wait_num); } + if (cli->cl_dirty_av) { + CWARN("%s: pipe loading av. %lu (b), max pipe space %lu (b), pipe " + "loading ratio %lu%%\n", obddev->obd_name, cli->cl_dirty_av, + cli->cl_dirty_max, (cli->cl_dirty_av * 100) / cli->cl_dirty_max); + } + + if (cli->cl_dirty_dmax) { + CWARN("%s: pipe dirty max %lu (b), pipe dirty min %lu (b)\n", + obddev->obd_name, cli->cl_dirty_dmax, cli->cl_dirty_dmin); + } + + /* Here we try to drop the security structure after destroy import, + * to avoid issue of "sleep in spinlock". + */ + class_import_get(cli->cl_import); + class_destroy_import(cli->cl_import); + ptlrpcs_import_drop_sec(cli->cl_import); + class_import_put(cli->cl_import); + cli->cl_import = NULL; + ldlm_put_ref(flags & OBD_OPT_FORCE); RETURN(0); } diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 494b562da25a0b79d1effd3c7df16437c72e70f7..8b3e32ced5ff6c8b7b0a503e990cd754860e6121 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -200,7 +200,6 @@ int ll_md_real_close(struct obd_export *md_exp, och = *och_p; *och_p = NULL; - up(&lli->lli_och_sem); /* diff --git a/lustre/llite/llite_capa.c b/lustre/llite/llite_capa.c index a19ac2f55fdb32c84d9e2047a21af60e4584a623..717f6bde060b976b4eeb9f33add63f83140fb86d 100644 --- a/lustre/llite/llite_capa.c +++ b/lustre/llite/llite_capa.c @@ -32,8 +32,9 @@ #include <linux/lustre_lite.h> #include "llite_internal.h" -static struct ptlrpc_thread ll_capa_thread; static struct list_head *ll_capa_list = &capa_list[CLIENT_CAPA]; +static struct ptlrpc_thread capa_thread; + static struct thread_ctl { struct completion ctl_starting; struct completion ctl_finishing; @@ -66,7 +67,7 @@ static inline int have_expired_capa(void) static int inline ll_capa_check_stop(void) { - return (ll_capa_thread.t_flags & SVC_STOPPING) ? 1: 0; + return (capa_thread.t_flags & SVC_STOPPING) ? 1: 0; } static int ll_renew_capa(struct obd_capa *ocapa) @@ -89,7 +90,7 @@ static int ll_renew_capa(struct obd_capa *ocapa) RETURN(rc); } -static int ll_capa_thread_main(void *arg) +static int ll_capa_thread(void *arg) { struct thread_ctl *ctl = arg; unsigned long flags; @@ -110,7 +111,7 @@ static int ll_capa_thread_main(void *arg) * letting starting function know, that we are ready and control may be * returned. */ - ll_capa_thread.t_flags = SVC_RUNNING; + capa_thread.t_flags = SVC_RUNNING; complete(&ctl->ctl_starting); while (1) { @@ -118,7 +119,7 @@ static int ll_capa_thread_main(void *arg) struct obd_capa *ocapa, *next = NULL; unsigned long expiry, sleep = CAPA_PRE_EXPIRY; - l_wait_event(ll_capa_thread.t_ctl_waitq, + l_wait_event(capa_thread.t_ctl_waitq, (have_expired_capa() || ll_capa_check_stop()), &lwi); @@ -154,7 +155,7 @@ static int ll_capa_thread_main(void *arg) schedule_timeout(sleep * HZ); } - ll_capa_thread.t_flags = SVC_STOPPED; + capa_thread.t_flags = SVC_STOPPED; /* this is SMP-safe way to finish thread. */ complete_and_exit(&ctl->ctl_finishing, 0); @@ -165,21 +166,21 @@ static int ll_capa_thread_main(void *arg) void ll_capa_timer_callback(unsigned long unused) { ENTRY; - wake_up(&ll_capa_thread.t_ctl_waitq); + wake_up(&capa_thread.t_ctl_waitq); EXIT; } -int ll_capa_start_thread(void) +int ll_capa_thread_start(void) { int rc; ENTRY; - LASSERT(ll_capa_thread.t_flags == 0); + LASSERT(capa_thread.t_flags == 0); init_completion(&ll_capa_ctl.ctl_starting); init_completion(&ll_capa_ctl.ctl_finishing); - init_waitqueue_head(&ll_capa_thread.t_ctl_waitq); + init_waitqueue_head(&capa_thread.t_ctl_waitq); - rc = kernel_thread(ll_capa_thread_main, &ll_capa_ctl, + rc = kernel_thread(ll_capa_thread, &ll_capa_ctl, (CLONE_VM | CLONE_FILES)); if (rc < 0) { CERROR("cannot start expired capa thread, " @@ -187,19 +188,19 @@ int ll_capa_start_thread(void) RETURN(rc); } wait_for_completion(&ll_capa_ctl.ctl_starting); - LASSERT(ll_capa_thread.t_flags == SVC_RUNNING); + LASSERT(capa_thread.t_flags == SVC_RUNNING); RETURN(0); } -void ll_capa_stop_thread(void) +void ll_capa_thread_stop(void) { ENTRY; - ll_capa_thread.t_flags = SVC_STOPPING; - wake_up(&ll_capa_thread.t_ctl_waitq); + capa_thread.t_flags = SVC_STOPPING; + wake_up(&capa_thread.t_ctl_waitq); wait_for_completion(&ll_capa_ctl.ctl_finishing); - LASSERT(ll_capa_thread.t_flags == SVC_STOPPED); - ll_capa_thread.t_flags = 0; + LASSERT(capa_thread.t_flags == SVC_STOPPED); + capa_thread.t_flags = 0; EXIT; } diff --git a/lustre/llite/llite_gns.c b/lustre/llite/llite_gns.c index 4109a083d1cdbfb23fdc60b9c2ca1b091c98d089..d2bdb1521eb54d1183da5b384f31e6a5e3a53892 100644 --- a/lustre/llite/llite_gns.c +++ b/lustre/llite/llite_gns.c @@ -522,7 +522,7 @@ void ll_gns_del_timer(struct ll_sb_info *sbi) * starts GNS control thread and waits for a signal it is up and work may be * continued. */ -int ll_gns_start_thread(void) +int ll_gns_thread_start(void) { int rc; ENTRY; @@ -545,7 +545,7 @@ int ll_gns_start_thread(void) } /* stops GNS control thread and waits its actual stop. */ -void ll_gns_stop_thread(void) +void ll_gns_thread_stop(void) { ENTRY; gns_thread.t_flags = SVC_STOPPING; diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index 1826223415a00f6bbf53581a18ec539e73db19de..dcf501bb3dfbd80dce9239e93d655fd7c5faf9b2 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -355,11 +355,12 @@ void ll_stime_record(struct ll_sb_info *sbi, struct timeval *start, struct obd_service_time *stime); /* llite_capa.c */ +int ll_capa_thread_start(void); +void ll_capa_thread_stop(void); + void ll_capa_timer_callback(unsigned long unused); -int ll_capa_start_thread(void); -void ll_capa_stop_thread(void); int ll_set_och_capa(struct inode *inode, struct lookup_intent *it, - struct obd_client_handle *och); + struct obd_client_handle *och); /* llite/dcache.c */ void ll_intent_drop_lock(struct lookup_intent *); @@ -375,8 +376,8 @@ int revalidate_it_finish(struct ptlrpc_request *request, int offset, /* llite/llite_gns.c */ -int ll_gns_start_thread(void); -void ll_gns_stop_thread(void); +int ll_gns_thread_start(void); +void ll_gns_thread_stop(void); int ll_gns_mount_object(struct dentry *dentry, struct vfsmount *mnt); diff --git a/lustre/llite/super.c b/lustre/llite/super.c index 1f9a484931cb383c27ff7cece2fdc5612edaac6f..d5d1be4ae426943c61160142075014c011e83973 100644 --- a/lustre/llite/super.c +++ b/lustre/llite/super.c @@ -129,7 +129,7 @@ static int __init init_lustre_lite(void) goto out; cleanup = 2; - rc = ll_gns_start_thread(); + rc = ll_gns_thread_start(); if (rc) goto out; @@ -137,7 +137,7 @@ static int __init init_lustre_lite(void) ll_capa_timer.data = 0; init_timer(&ll_capa_timer); - rc = ll_capa_start_thread(); + rc = ll_capa_thread_start(); if (rc) goto out; @@ -162,8 +162,8 @@ static void __exit exit_lustre_lite(void) unregister_filesystem(&lustre_fs_type); del_timer(&ll_capa_timer); - ll_capa_stop_thread(); - ll_gns_stop_thread(); + ll_capa_thread_stop(); + ll_gns_thread_stop(); LASSERTF(kmem_cache_destroy(ll_file_data_slab) == 0, "couldn't destroy ll_file_data slab\n"); diff --git a/lustre/llite/super25.c b/lustre/llite/super25.c index e758f21a5ed09d3997e1a4874f9bff4d2dac3ede..0d55f057c67f93ea05a932892db80d2a764f91b7 100644 --- a/lustre/llite/super25.c +++ b/lustre/llite/super25.c @@ -175,7 +175,7 @@ static int __init init_lustre_lite(void) goto out; cleanup = 2; - rc = ll_gns_start_thread(); + rc = ll_gns_thread_start(); if (rc) goto out; @@ -183,7 +183,7 @@ static int __init init_lustre_lite(void) ll_capa_timer.data = 0; init_timer(&ll_capa_timer); - rc = ll_capa_start_thread(); + rc = ll_capa_thread_start(); if (rc) goto out; @@ -206,8 +206,8 @@ static void __exit exit_lustre_lite(void) unregister_filesystem(&lustre_lite_fs_type); del_timer(&ll_capa_timer); - ll_capa_stop_thread(); - ll_gns_stop_thread(); + ll_capa_thread_stop(); + ll_gns_thread_stop(); ll_destroy_inodecache(); LASSERTF(kmem_cache_destroy(ll_file_data_slab) == 0, diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index 529b06474a0553b3d3d5b39168184d609a6ce416..b2463ac83ae019aa829b369c876ee006ad1c8b03 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -1314,6 +1314,7 @@ static int brw_interpret_oap(struct ptlrpc_request *request, CDEBUG(D_INODE, "request %p aa %p rc %d\n", request, aa, rc); cli = aa->aa_cli; + /* in failout recovery we ignore writeback failure and want * to just tell llite to unlock the page and continue */ if (request->rq_reqmsg->opc == OST_WRITE && @@ -1333,8 +1334,6 @@ static int brw_interpret_oap(struct ptlrpc_request *request, lprocfs_stime_record(&cli->cl_read_stime, &now, &request->rq_rpcd_start); - - /* We need to decrement before osc_ap_completion->osc_wake_cache_waiters * is called so we know whether to go to sync BRWs or wait for more * RPCs to complete */ @@ -1870,6 +1869,24 @@ static int osc_enter_cache(struct client_obd *cli, struct lov_oinfo *loi, if (cli->cl_dirty_max < PAGE_SIZE) return(-EDQUOT); + if (~0ul - cli->cl_dirty_sum <= cli->cl_dirty) { + cli->cl_dirty_av = (cli->cl_dirty_av + + (cli->cl_dirty_sum / cli->cl_dirty_num)) / 2; + cli->cl_dirty_num = 0; + cli->cl_dirty_sum = 0; + } else { + if (cli->cl_dirty_num) + cli->cl_dirty_av = (cli->cl_dirty_sum / cli->cl_dirty_num); + } + + cli->cl_dirty_num++; + cli->cl_dirty_sum += cli->cl_dirty; + + if (cli->cl_dirty > cli->cl_dirty_dmax) + cli->cl_dirty_dmax = cli->cl_dirty; + if (cli->cl_dirty < cli->cl_dirty_dmin) + cli->cl_dirty_dmin = cli->cl_dirty; + /* Hopefully normal case - cache space and write credits available */ if (cli->cl_dirty + PAGE_SIZE <= cli->cl_dirty_max && cli->cl_avail_grant >= PAGE_SIZE) { @@ -1924,6 +1941,24 @@ static void osc_exit_cache(struct client_obd *cli, struct osc_async_page *oap, return; } + if (~0ul - cli->cl_dirty_sum <= cli->cl_dirty) { + cli->cl_dirty_av = (cli->cl_dirty_av + + (cli->cl_dirty_sum / cli->cl_dirty_num)) / 2; + cli->cl_dirty_num = 0; + cli->cl_dirty_sum = 0; + } else { + if (cli->cl_dirty_num) + cli->cl_dirty_av = (cli->cl_dirty_sum / cli->cl_dirty_num); + } + + cli->cl_dirty_num++; + cli->cl_dirty_sum += cli->cl_dirty; + + if (cli->cl_dirty > cli->cl_dirty_dmax) + cli->cl_dirty_dmax = cli->cl_dirty; + if (cli->cl_dirty < cli->cl_dirty_dmin) + cli->cl_dirty_dmin = cli->cl_dirty; + oap->oap_brw_flags &= ~OBD_BRW_FROM_GRANT; cli->cl_dirty -= PAGE_SIZE; if (!sent) {