From mario.bambagini at gmail.com Wed Mar 1 23:57:09 2017 From: mario.bambagini at gmail.com (Mario Bambagini) Date: Thu, 2 Mar 2017 00:57:09 +0100 Subject: [lustre-devel] [PATCH] staging: lustre: fix sparse warning about different address spaces Message-ID: <1488412629-20859-1-git-send-email-mario.bambagini@gmail.com> fixed the following sparse warning by adding proper cast: drivers/staging//lustre/lustre/obdclass/obd_config.c:1055:74: warning: incorrect type in argument 2 (different address spaces) drivers/staging//lustre/lustre/obdclass/obd_config.c:1055:74: expected char const [noderef] * drivers/staging//lustre/lustre/obdclass/obd_config.c:1055:74: got char *[assigned] sval Signed-off-by: Mario Bambagini --- drivers/staging/lustre/lustre/obdclass/obd_config.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/obdclass/obd_config.c b/drivers/staging/lustre/lustre/obdclass/obd_config.c index 9ca84c7..8fce88f 100644 --- a/drivers/staging/lustre/lustre/obdclass/obd_config.c +++ b/drivers/staging/lustre/lustre/obdclass/obd_config.c @@ -1052,7 +1052,8 @@ int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars, oldfs = get_fs(); set_fs(KERNEL_DS); - rc = var->fops->write(&fakefile, sval, + rc = var->fops->write(&fakefile, + (const char __user *)sval, vallen, NULL); set_fs(oldfs); } -- 2.1.4 From julia.lawall at lip6.fr Sun Mar 5 17:15:23 2017 From: julia.lawall at lip6.fr (Julia Lawall) Date: Sun, 5 Mar 2017 18:15:23 +0100 (CET) Subject: [lustre-devel] [Outreachy kernel] [PATCH 5/5] staging: lustre: osc_page.c: Use list_for_each_entry_safe In-Reply-To: <1488733610-22289-6-git-send-email-singhalsimran0@gmail.com> References: <1488733610-22289-1-git-send-email-singhalsimran0@gmail.com> <1488733610-22289-6-git-send-email-singhalsimran0@gmail.com> Message-ID: On Sun, 5 Mar 2017, simran singhal wrote: > Doubly linked lists which are iterated using list_empty > and list_entry macros have been replaced with list_for_each_entry_safe > macro. > This makes the iteration simpler and more readable. > > This patch replaces the while loop containing list_empty and list_entry > with list_for_each_entry_safe. list_for_each_entry_safe is only needed when the current element is removed from the list within the loop body. If that is not the case, you can just use list_for_each_entry. julia > > This was done with Coccinelle. > > @@ > expression E1; > identifier I1, I2; > type T; > iterator name list_for_each_entry_safe; > @@ > > T *I1; > + T *tmp; > ... > - while (list_empty(&E1) == 0) > + list_for_each_entry_safe (I1, tmp, &E1, I2) > { > ...when != T *I1; > - I1 = list_entry(E1.next, T, I2); > ... > } > > Signed-off-by: simran singhal > --- > drivers/staging/lustre/lustre/osc/osc_page.c | 11 ++++------- > 1 file changed, 4 insertions(+), 7 deletions(-) > > diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c > index ed8a0dc..e8b974f 100644 > --- a/drivers/staging/lustre/lustre/osc/osc_page.c > +++ b/drivers/staging/lustre/lustre/osc/osc_page.c > @@ -542,6 +542,7 @@ long osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, > struct cl_object *clobj = NULL; > struct cl_page **pvec; > struct osc_page *opg; > + struct osc_page *tmp; > int maxscan = 0; > long count = 0; > int index = 0; > @@ -572,7 +573,7 @@ long osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, > if (force) > cli->cl_lru_reclaim++; > maxscan = min(target << 1, atomic_long_read(&cli->cl_lru_in_list)); > - while (!list_empty(&cli->cl_lru_list)) { > + list_for_each_entry_safe(opg, tmp, &cli->cl_lru_list, ops_lru) { > struct cl_page *page; > bool will_free = false; > > @@ -582,8 +583,6 @@ long osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, > if (--maxscan < 0) > break; > > - opg = list_entry(cli->cl_lru_list.next, struct osc_page, > - ops_lru); > page = opg->ops_cl.cpl_page; > if (lru_page_busy(cli, page)) { > list_move_tail(&opg->ops_lru, &cli->cl_lru_list); > @@ -1043,6 +1042,7 @@ unsigned long osc_cache_shrink_scan(struct shrinker *sk, > { > struct client_obd *stop_anchor = NULL; > struct client_obd *cli; > + struct client_obd *tmp; > struct lu_env *env; > long shrank = 0; > u16 refcheck; > @@ -1059,10 +1059,7 @@ unsigned long osc_cache_shrink_scan(struct shrinker *sk, > return SHRINK_STOP; > > spin_lock(&osc_shrink_lock); > - while (!list_empty(&osc_shrink_list)) { > - cli = list_entry(osc_shrink_list.next, struct client_obd, > - cl_shrink_list); > - > + list_for_each_entry_safe(cli, tmp, &osc_shrink_list, cl_shrink_list) { > if (!stop_anchor) > stop_anchor = cli; > else if (cli == stop_anchor) > -- > 2.7.4 > > -- > You received this message because you are subscribed to the Google Groups "outreachy-kernel" group. > To unsubscribe from this group and stop receiving emails from it, send an email to outreachy-kernel+unsubscribe at googlegroups.com. > To post to this group, send email to outreachy-kernel at googlegroups.com. > To view this discussion on the web visit https://groups.google.com/d/msgid/outreachy-kernel/1488733610-22289-6-git-send-email-singhalsimran0%40gmail.com. > For more options, visit https://groups.google.com/d/optout. > From julia.lawall at lip6.fr Sun Mar 5 17:17:20 2017 From: julia.lawall at lip6.fr (Julia Lawall) Date: Sun, 5 Mar 2017 18:17:20 +0100 (CET) Subject: [lustre-devel] [Outreachy kernel] [PATCH 5/5] staging: lustre: osc_page.c: Use list_for_each_entry_safe In-Reply-To: <1488733610-22289-6-git-send-email-singhalsimran0@gmail.com> References: <1488733610-22289-1-git-send-email-singhalsimran0@gmail.com> <1488733610-22289-6-git-send-email-singhalsimran0@gmail.com> Message-ID: By the way, the above subject line is not correct. Normally one does not put .c/.h in the subject line. Indeed, there is not really any deterministic algorithm for choosing the subject line. You need to run git log --oneline filename to see what others have done. julia On Sun, 5 Mar 2017, simran singhal wrote: > Doubly linked lists which are iterated using list_empty > and list_entry macros have been replaced with list_for_each_entry_safe > macro. > This makes the iteration simpler and more readable. > > This patch replaces the while loop containing list_empty and list_entry > with list_for_each_entry_safe. > > This was done with Coccinelle. > > @@ > expression E1; > identifier I1, I2; > type T; > iterator name list_for_each_entry_safe; > @@ > > T *I1; > + T *tmp; > ... > - while (list_empty(&E1) == 0) > + list_for_each_entry_safe (I1, tmp, &E1, I2) > { > ...when != T *I1; > - I1 = list_entry(E1.next, T, I2); > ... > } > > Signed-off-by: simran singhal > --- > drivers/staging/lustre/lustre/osc/osc_page.c | 11 ++++------- > 1 file changed, 4 insertions(+), 7 deletions(-) > > diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c > index ed8a0dc..e8b974f 100644 > --- a/drivers/staging/lustre/lustre/osc/osc_page.c > +++ b/drivers/staging/lustre/lustre/osc/osc_page.c > @@ -542,6 +542,7 @@ long osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, > struct cl_object *clobj = NULL; > struct cl_page **pvec; > struct osc_page *opg; > + struct osc_page *tmp; > int maxscan = 0; > long count = 0; > int index = 0; > @@ -572,7 +573,7 @@ long osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, > if (force) > cli->cl_lru_reclaim++; > maxscan = min(target << 1, atomic_long_read(&cli->cl_lru_in_list)); > - while (!list_empty(&cli->cl_lru_list)) { > + list_for_each_entry_safe(opg, tmp, &cli->cl_lru_list, ops_lru) { > struct cl_page *page; > bool will_free = false; > > @@ -582,8 +583,6 @@ long osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, > if (--maxscan < 0) > break; > > - opg = list_entry(cli->cl_lru_list.next, struct osc_page, > - ops_lru); > page = opg->ops_cl.cpl_page; > if (lru_page_busy(cli, page)) { > list_move_tail(&opg->ops_lru, &cli->cl_lru_list); > @@ -1043,6 +1042,7 @@ unsigned long osc_cache_shrink_scan(struct shrinker *sk, > { > struct client_obd *stop_anchor = NULL; > struct client_obd *cli; > + struct client_obd *tmp; > struct lu_env *env; > long shrank = 0; > u16 refcheck; > @@ -1059,10 +1059,7 @@ unsigned long osc_cache_shrink_scan(struct shrinker *sk, > return SHRINK_STOP; > > spin_lock(&osc_shrink_lock); > - while (!list_empty(&osc_shrink_list)) { > - cli = list_entry(osc_shrink_list.next, struct client_obd, > - cl_shrink_list); > - > + list_for_each_entry_safe(cli, tmp, &osc_shrink_list, cl_shrink_list) { > if (!stop_anchor) > stop_anchor = cli; > else if (cli == stop_anchor) > -- > 2.7.4 > > -- > You received this message because you are subscribed to the Google Groups "outreachy-kernel" group. > To unsubscribe from this group and stop receiving emails from it, send an email to outreachy-kernel+unsubscribe at googlegroups.com. > To post to this group, send email to outreachy-kernel at googlegroups.com. > To view this discussion on the web visit https://groups.google.com/d/msgid/outreachy-kernel/1488733610-22289-6-git-send-email-singhalsimran0%40gmail.com. > For more options, visit https://groups.google.com/d/optout. > From julia.lawall at lip6.fr Sun Mar 5 17:20:27 2017 From: julia.lawall at lip6.fr (Julia Lawall) Date: Sun, 5 Mar 2017 18:20:27 +0100 (CET) Subject: [lustre-devel] [Outreachy kernel] [PATCH 5/5] staging: lustre: osc_page.c: Use list_for_each_entry_safe In-Reply-To: References: <1488733610-22289-1-git-send-email-singhalsimran0@gmail.com> <1488733610-22289-6-git-send-email-singhalsimran0@gmail.com> Message-ID: On Sun, 5 Mar 2017, Julia Lawall wrote: > > > On Sun, 5 Mar 2017, simran singhal wrote: > > > Doubly linked lists which are iterated using list_empty > > and list_entry macros have been replaced with list_for_each_entry_safe > > macro. > > This makes the iteration simpler and more readable. > > > > This patch replaces the while loop containing list_empty and list_entry > > with list_for_each_entry_safe. > > list_for_each_entry_safe is only needed when the current element is > removed from the list within the loop body. If that is not the case, you > can just use list_for_each_entry. Sorry, my comment was likely completely off the mark here. I was thinking that the original code was using list_for_each. With the while (!list_empty pattern, the safe version is definitely needed. julia > > julia > > > > > > This was done with Coccinelle. > > > > @@ > > expression E1; > > identifier I1, I2; > > type T; > > iterator name list_for_each_entry_safe; > > @@ > > > > T *I1; > > + T *tmp; > > ... > > - while (list_empty(&E1) == 0) > > + list_for_each_entry_safe (I1, tmp, &E1, I2) > > { > > ...when != T *I1; > > - I1 = list_entry(E1.next, T, I2); > > ... > > } > > > > Signed-off-by: simran singhal > > --- > > drivers/staging/lustre/lustre/osc/osc_page.c | 11 ++++------- > > 1 file changed, 4 insertions(+), 7 deletions(-) > > > > diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c > > index ed8a0dc..e8b974f 100644 > > --- a/drivers/staging/lustre/lustre/osc/osc_page.c > > +++ b/drivers/staging/lustre/lustre/osc/osc_page.c > > @@ -542,6 +542,7 @@ long osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, > > struct cl_object *clobj = NULL; > > struct cl_page **pvec; > > struct osc_page *opg; > > + struct osc_page *tmp; > > int maxscan = 0; > > long count = 0; > > int index = 0; > > @@ -572,7 +573,7 @@ long osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, > > if (force) > > cli->cl_lru_reclaim++; > > maxscan = min(target << 1, atomic_long_read(&cli->cl_lru_in_list)); > > - while (!list_empty(&cli->cl_lru_list)) { > > + list_for_each_entry_safe(opg, tmp, &cli->cl_lru_list, ops_lru) { > > struct cl_page *page; > > bool will_free = false; > > > > @@ -582,8 +583,6 @@ long osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, > > if (--maxscan < 0) > > break; > > > > - opg = list_entry(cli->cl_lru_list.next, struct osc_page, > > - ops_lru); > > page = opg->ops_cl.cpl_page; > > if (lru_page_busy(cli, page)) { > > list_move_tail(&opg->ops_lru, &cli->cl_lru_list); > > @@ -1043,6 +1042,7 @@ unsigned long osc_cache_shrink_scan(struct shrinker *sk, > > { > > struct client_obd *stop_anchor = NULL; > > struct client_obd *cli; > > + struct client_obd *tmp; > > struct lu_env *env; > > long shrank = 0; > > u16 refcheck; > > @@ -1059,10 +1059,7 @@ unsigned long osc_cache_shrink_scan(struct shrinker *sk, > > return SHRINK_STOP; > > > > spin_lock(&osc_shrink_lock); > > - while (!list_empty(&osc_shrink_list)) { > > - cli = list_entry(osc_shrink_list.next, struct client_obd, > > - cl_shrink_list); > > - > > + list_for_each_entry_safe(cli, tmp, &osc_shrink_list, cl_shrink_list) { > > if (!stop_anchor) > > stop_anchor = cli; > > else if (cli == stop_anchor) > > -- > > 2.7.4 > > > > -- > > You received this message because you are subscribed to the Google Groups "outreachy-kernel" group. > > To unsubscribe from this group and stop receiving emails from it, send an email to outreachy-kernel+unsubscribe at googlegroups.com. > > To post to this group, send email to outreachy-kernel at googlegroups.com. > > To view this discussion on the web visit https://groups.google.com/d/msgid/outreachy-kernel/1488733610-22289-6-git-send-email-singhalsimran0%40gmail.com. > > For more options, visit https://groups.google.com/d/optout. > > > From julia.lawall at lip6.fr Sun Mar 5 17:34:05 2017 From: julia.lawall at lip6.fr (Julia Lawall) Date: Sun, 5 Mar 2017 18:34:05 +0100 (CET) Subject: [lustre-devel] [Outreachy kernel] [PATCH 1/5] staging: lustre: Use list_for_each_entry_safe In-Reply-To: <1488733610-22289-2-git-send-email-singhalsimran0@gmail.com> References: <1488733610-22289-1-git-send-email-singhalsimran0@gmail.com> <1488733610-22289-2-git-send-email-singhalsimran0@gmail.com> Message-ID: On Sun, 5 Mar 2017, simran singhal wrote: > Doubly linked lists which are iterated using list_empty > and list_entry macros have been replaced with list_for_each_entry_safe > macro. > This makes the iteration simpler and more readable. > > This patch replaces the while loop containing list_empty and list_entry > with list_for_each_entry_safe. > > This was done with Coccinelle. > > @@ > expression E1; > identifier I1, I2; > type T; > iterator name list_for_each_entry_safe; > @@ > > T *I1; > + T *tmp; > ... The function that is modified in this patch actually has another opportunity. That doesn't get transformed because with ... Coccinelle matches the shortest path between what comes before and what comes after, and so it only matches the first while loop. You could sort of fix the problem by putting when any on the ... That allows anything in the path, including other while loops. That though will mean that you will try to add two instances of the tmp declaration after the declaration of I1. Coccinelle allows adding only one thing, unless the + is replaced by ++. But if you do that, you will get two decarations of tmp. So either make the second change by hand, or let Coccinelle do it an remove the second declaration of tmp by hand. julia > - while (list_empty(&E1) == 0) > + list_for_each_entry_safe (I1, tmp, &E1, I2) > { > ...when != T *I1; > - I1 = list_entry(E1.next, T, I2); > ... > } > > Signed-off-by: simran singhal > --- > drivers/staging/lustre/lustre/ptlrpc/service.c | 5 ++--- > 1 file changed, 2 insertions(+), 3 deletions(-) > > diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c > index b8091c1..4e7dc1d 100644 > --- a/drivers/staging/lustre/lustre/ptlrpc/service.c > +++ b/drivers/staging/lustre/lustre/ptlrpc/service.c > @@ -2314,6 +2314,7 @@ static void ptlrpc_svcpt_stop_threads(struct ptlrpc_service_part *svcpt) > { > struct l_wait_info lwi = { 0 }; > struct ptlrpc_thread *thread; > + struct ptlrpc_thread *tmp; > LIST_HEAD(zombie); > > CDEBUG(D_INFO, "Stopping threads for service %s\n", > @@ -2329,9 +2330,7 @@ static void ptlrpc_svcpt_stop_threads(struct ptlrpc_service_part *svcpt) > > wake_up_all(&svcpt->scp_waitq); > > - while (!list_empty(&svcpt->scp_threads)) { > - thread = list_entry(svcpt->scp_threads.next, > - struct ptlrpc_thread, t_link); > + list_for_each_entry_safe(thread, tmp, &svcpt->scp_threads, t_link) { > if (thread_is_stopped(thread)) { > list_del(&thread->t_link); > list_add(&thread->t_link, &zombie); > -- > 2.7.4 > > -- > You received this message because you are subscribed to the Google Groups "outreachy-kernel" group. > To unsubscribe from this group and stop receiving emails from it, send an email to outreachy-kernel+unsubscribe at googlegroups.com. > To post to this group, send email to outreachy-kernel at googlegroups.com. > To view this discussion on the web visit https://groups.google.com/d/msgid/outreachy-kernel/1488733610-22289-2-git-send-email-singhalsimran0%40gmail.com. > For more options, visit https://groups.google.com/d/optout. > From julia.lawall at lip6.fr Sun Mar 5 17:39:07 2017 From: julia.lawall at lip6.fr (Julia Lawall) Date: Sun, 5 Mar 2017 18:39:07 +0100 (CET) Subject: [lustre-devel] [Outreachy kernel] [PATCH 2/5] staging: lustre: ptlrpc: Use list_for_each_entry_safe In-Reply-To: <1488733610-22289-3-git-send-email-singhalsimran0@gmail.com> References: <1488733610-22289-1-git-send-email-singhalsimran0@gmail.com> <1488733610-22289-3-git-send-email-singhalsimran0@gmail.com> Message-ID: On Sun, 5 Mar 2017, simran singhal wrote: > Doubly linked lists which are iterated using list_empty > and list_entry macros have been replaced with list_for_each_entry_safe > macro. > This makes the iteration simpler and more readable. > > This patch replaces the while loop containing list_empty and list_entry > with list_for_each_entry_safe. > > This was done with Coccinelle. > > @@ > expression E1; > identifier I1, I2; > type T; > iterator name list_for_each_entry_safe; > @@ > > T *I1; > + T *tmp; > ... > - while (list_empty(&E1) == 0) > + list_for_each_entry_safe (I1, tmp, &E1, I2) > { > ...when != T *I1; > - I1 = list_entry(E1.next, T, I2); > ... > } > > Signed-off-by: simran singhal > --- > drivers/staging/lustre/lustre/ptlrpc/sec_gc.c | 5 ++--- > 1 file changed, 2 insertions(+), 3 deletions(-) > > diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c b/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c > index 8ffd000..fe1c0af 100644 > --- a/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c > +++ b/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c > @@ -98,12 +98,11 @@ void sptlrpc_gc_del_sec(struct ptlrpc_sec *sec) > static void sec_process_ctx_list(void) > { > struct ptlrpc_cli_ctx *ctx; > + struct ptlrpc_cli_ctx *tmp; Another improvement would be to define both variables at once: T *I1 + , *tmp ; julia > > spin_lock(&sec_gc_ctx_list_lock); > > - while (!list_empty(&sec_gc_ctx_list)) { > - ctx = list_entry(sec_gc_ctx_list.next, > - struct ptlrpc_cli_ctx, cc_gc_chain); > + list_for_each_entry_safe(ctx, tmp, &sec_gc_ctx_list, cc_gc_chain) { > list_del_init(&ctx->cc_gc_chain); > spin_unlock(&sec_gc_ctx_list_lock); > > -- > 2.7.4 > > -- > You received this message because you are subscribed to the Google Groups "outreachy-kernel" group. > To unsubscribe from this group and stop receiving emails from it, send an email to outreachy-kernel+unsubscribe at googlegroups.com. > To post to this group, send email to outreachy-kernel at googlegroups.com. > To view this discussion on the web visit https://groups.google.com/d/msgid/outreachy-kernel/1488733610-22289-3-git-send-email-singhalsimran0%40gmail.com. > For more options, visit https://groups.google.com/d/optout. > From julia.lawall at lip6.fr Sun Mar 5 17:43:32 2017 From: julia.lawall at lip6.fr (Julia Lawall) Date: Sun, 5 Mar 2017 18:43:32 +0100 (CET) Subject: [lustre-devel] [Outreachy kernel] [PATCH 2/5] staging: lustre: ptlrpc: Use list_for_each_entry_safe In-Reply-To: References: <1488733610-22289-1-git-send-email-singhalsimran0@gmail.com> <1488733610-22289-3-git-send-email-singhalsimran0@gmail.com> Message-ID: On Sun, 5 Mar 2017, SIMRAN SINGHAL wrote: > On Sun, Mar 5, 2017 at 11:09 PM, Julia Lawall wrote: > > > > > > On Sun, 5 Mar 2017, simran singhal wrote: > > > >> Doubly linked lists which are iterated using list_empty > >> and list_entry macros have been replaced with list_for_each_entry_safe > >> macro. > >> This makes the iteration simpler and more readable. > >> > >> This patch replaces the while loop containing list_empty and list_entry > >> with list_for_each_entry_safe. > >> > >> This was done with Coccinelle. > >> > >> @@ > >> expression E1; > >> identifier I1, I2; > >> type T; > >> iterator name list_for_each_entry_safe; > >> @@ > >> > >> T *I1; > >> + T *tmp; > >> ... > >> - while (list_empty(&E1) == 0) > >> + list_for_each_entry_safe (I1, tmp, &E1, I2) > >> { > >> ...when != T *I1; > >> - I1 = list_entry(E1.next, T, I2); > >> ... > >> } > >> > >> Signed-off-by: simran singhal > >> --- > >> drivers/staging/lustre/lustre/ptlrpc/sec_gc.c | 5 ++--- > >> 1 file changed, 2 insertions(+), 3 deletions(-) > >> > >> diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c b/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c > >> index 8ffd000..fe1c0af 100644 > >> --- a/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c > >> +++ b/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c > >> @@ -98,12 +98,11 @@ void sptlrpc_gc_del_sec(struct ptlrpc_sec *sec) > >> static void sec_process_ctx_list(void) > >> { > >> struct ptlrpc_cli_ctx *ctx; > >> + struct ptlrpc_cli_ctx *tmp; > > > > Another improvement would be to define both variables at once: > > > > T *I1 > > + , *tmp > > ; > > > This is particulary for this patch or for all the patches of this patch-series. All, I would guess. Unless the line gets too long. julia > > > julia > > > >> > >> spin_lock(&sec_gc_ctx_list_lock); > >> > >> - while (!list_empty(&sec_gc_ctx_list)) { > >> - ctx = list_entry(sec_gc_ctx_list.next, > >> - struct ptlrpc_cli_ctx, cc_gc_chain); > >> + list_for_each_entry_safe(ctx, tmp, &sec_gc_ctx_list, cc_gc_chain) { > >> list_del_init(&ctx->cc_gc_chain); > >> spin_unlock(&sec_gc_ctx_list_lock); > >> > >> -- > >> 2.7.4 > >> > >> -- > >> You received this message because you are subscribed to the Google Groups "outreachy-kernel" group. > >> To unsubscribe from this group and stop receiving emails from it, send an email to outreachy-kernel+unsubscribe at googlegroups.com. > >> To post to this group, send email to outreachy-kernel at googlegroups.com. > >> To view this discussion on the web visit https://groups.google.com/d/msgid/outreachy-kernel/1488733610-22289-3-git-send-email-singhalsimran0%40gmail.com. > >> For more options, visit https://groups.google.com/d/optout. > >> > From julia.lawall at lip6.fr Sun Mar 5 17:48:46 2017 From: julia.lawall at lip6.fr (Julia Lawall) Date: Sun, 5 Mar 2017 18:48:46 +0100 (CET) Subject: [lustre-devel] [Outreachy kernel] [PATCH 5/5] staging: lustre: osc_page.c: Use list_for_each_entry_safe In-Reply-To: References: <1488733610-22289-1-git-send-email-singhalsimran0@gmail.com> <1488733610-22289-6-git-send-email-singhalsimran0@gmail.com> Message-ID: On Sun, 5 Mar 2017, SIMRAN SINGHAL wrote: > On Sun, Mar 5, 2017 at 10:47 PM, Julia Lawall wrote: > > By the way, the above subject line is not correct. Normally one does not > > put .c/.h in the subject line. Indeed, there is not really any > > deterministic algorithm for choosing the subject line. You need to run > > git log --oneline filename to see what others have done. > > So this would be fine Subject:- > staging: lustre: osc_page: Use list_for_each_entry_safe Looking at the result of git log --oneline, I would say: staging: lustre: osc: For example that it what is used by 86df598, which also only changes the file modified by this patch. julia > > > > > julia > > > > On Sun, 5 Mar 2017, simran singhal wrote: > > > >> Doubly linked lists which are iterated using list_empty > >> and list_entry macros have been replaced with list_for_each_entry_safe > >> macro. > >> This makes the iteration simpler and more readable. > >> > >> This patch replaces the while loop containing list_empty and list_entry > >> with list_for_each_entry_safe. > >> > >> This was done with Coccinelle. > >> > >> @@ > >> expression E1; > >> identifier I1, I2; > >> type T; > >> iterator name list_for_each_entry_safe; > >> @@ > >> > >> T *I1; > >> + T *tmp; > >> ... > >> - while (list_empty(&E1) == 0) > >> + list_for_each_entry_safe (I1, tmp, &E1, I2) > >> { > >> ...when != T *I1; > >> - I1 = list_entry(E1.next, T, I2); > >> ... > >> } > >> > >> Signed-off-by: simran singhal > >> --- > >> drivers/staging/lustre/lustre/osc/osc_page.c | 11 ++++------- > >> 1 file changed, 4 insertions(+), 7 deletions(-) > >> > >> diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c > >> index ed8a0dc..e8b974f 100644 > >> --- a/drivers/staging/lustre/lustre/osc/osc_page.c > >> +++ b/drivers/staging/lustre/lustre/osc/osc_page.c > >> @@ -542,6 +542,7 @@ long osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, > >> struct cl_object *clobj = NULL; > >> struct cl_page **pvec; > >> struct osc_page *opg; > >> + struct osc_page *tmp; > >> int maxscan = 0; > >> long count = 0; > >> int index = 0; > >> @@ -572,7 +573,7 @@ long osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, > >> if (force) > >> cli->cl_lru_reclaim++; > >> maxscan = min(target << 1, atomic_long_read(&cli->cl_lru_in_list)); > >> - while (!list_empty(&cli->cl_lru_list)) { > >> + list_for_each_entry_safe(opg, tmp, &cli->cl_lru_list, ops_lru) { > >> struct cl_page *page; > >> bool will_free = false; > >> > >> @@ -582,8 +583,6 @@ long osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, > >> if (--maxscan < 0) > >> break; > >> > >> - opg = list_entry(cli->cl_lru_list.next, struct osc_page, > >> - ops_lru); > >> page = opg->ops_cl.cpl_page; > >> if (lru_page_busy(cli, page)) { > >> list_move_tail(&opg->ops_lru, &cli->cl_lru_list); > >> @@ -1043,6 +1042,7 @@ unsigned long osc_cache_shrink_scan(struct shrinker *sk, > >> { > >> struct client_obd *stop_anchor = NULL; > >> struct client_obd *cli; > >> + struct client_obd *tmp; > >> struct lu_env *env; > >> long shrank = 0; > >> u16 refcheck; > >> @@ -1059,10 +1059,7 @@ unsigned long osc_cache_shrink_scan(struct shrinker *sk, > >> return SHRINK_STOP; > >> > >> spin_lock(&osc_shrink_lock); > >> - while (!list_empty(&osc_shrink_list)) { > >> - cli = list_entry(osc_shrink_list.next, struct client_obd, > >> - cl_shrink_list); > >> - > >> + list_for_each_entry_safe(cli, tmp, &osc_shrink_list, cl_shrink_list) { > >> if (!stop_anchor) > >> stop_anchor = cli; > >> else if (cli == stop_anchor) > >> -- > >> 2.7.4 > >> > >> -- > >> You received this message because you are subscribed to the Google Groups "outreachy-kernel" group. > >> To unsubscribe from this group and stop receiving emails from it, send an email to outreachy-kernel+unsubscribe at googlegroups.com. > >> To post to this group, send email to outreachy-kernel at googlegroups.com. > >> To view this discussion on the web visit https://groups.google.com/d/msgid/outreachy-kernel/1488733610-22289-6-git-send-email-singhalsimran0%40gmail.com. > >> For more options, visit https://groups.google.com/d/optout. > >> > From julia.lawall at lip6.fr Sun Mar 5 17:52:21 2017 From: julia.lawall at lip6.fr (Julia Lawall) Date: Sun, 5 Mar 2017 18:52:21 +0100 (CET) Subject: [lustre-devel] [Outreachy kernel] [PATCH 5/5] staging: lustre: osc_page.c: Use list_for_each_entry_safe In-Reply-To: References: <1488733610-22289-1-git-send-email-singhalsimran0@gmail.com> <1488733610-22289-6-git-send-email-singhalsimran0@gmail.com> Message-ID: On Sun, 5 Mar 2017, SIMRAN SINGHAL wrote: > On Sun, Mar 5, 2017 at 11:18 PM, Julia Lawall wrote: > > > > > > On Sun, 5 Mar 2017, SIMRAN SINGHAL wrote: > > > >> On Sun, Mar 5, 2017 at 10:47 PM, Julia Lawall wrote: > >> > By the way, the above subject line is not correct. Normally one does not > >> > put .c/.h in the subject line. Indeed, there is not really any > >> > deterministic algorithm for choosing the subject line. You need to run > >> > git log --oneline filename to see what others have done. > >> > >> So this would be fine Subject:- > >> staging: lustre: osc_page: Use list_for_each_entry_safe > > > > Looking at the result of git log --oneline, I would say: > > > > staging: lustre: osc: > > > > For example that it what is used by 86df598, which also only changes the > > file modified by this patch. > > > Actually, I can't use this as its already subject of one of a patch of > this patch > series. OK, then what you suggested would be ok. julia > > > julia > > > >> > >> > > >> > julia > >> > > >> > On Sun, 5 Mar 2017, simran singhal wrote: > >> > > >> >> Doubly linked lists which are iterated using list_empty > >> >> and list_entry macros have been replaced with list_for_each_entry_safe > >> >> macro. > >> >> This makes the iteration simpler and more readable. > >> >> > >> >> This patch replaces the while loop containing list_empty and list_entry > >> >> with list_for_each_entry_safe. > >> >> > >> >> This was done with Coccinelle. > >> >> > >> >> @@ > >> >> expression E1; > >> >> identifier I1, I2; > >> >> type T; > >> >> iterator name list_for_each_entry_safe; > >> >> @@ > >> >> > >> >> T *I1; > >> >> + T *tmp; > >> >> ... > >> >> - while (list_empty(&E1) == 0) > >> >> + list_for_each_entry_safe (I1, tmp, &E1, I2) > >> >> { > >> >> ...when != T *I1; > >> >> - I1 = list_entry(E1.next, T, I2); > >> >> ... > >> >> } > >> >> > >> >> Signed-off-by: simran singhal > >> >> --- > >> >> drivers/staging/lustre/lustre/osc/osc_page.c | 11 ++++------- > >> >> 1 file changed, 4 insertions(+), 7 deletions(-) > >> >> > >> >> diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c > >> >> index ed8a0dc..e8b974f 100644 > >> >> --- a/drivers/staging/lustre/lustre/osc/osc_page.c > >> >> +++ b/drivers/staging/lustre/lustre/osc/osc_page.c > >> >> @@ -542,6 +542,7 @@ long osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, > >> >> struct cl_object *clobj = NULL; > >> >> struct cl_page **pvec; > >> >> struct osc_page *opg; > >> >> + struct osc_page *tmp; > >> >> int maxscan = 0; > >> >> long count = 0; > >> >> int index = 0; > >> >> @@ -572,7 +573,7 @@ long osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, > >> >> if (force) > >> >> cli->cl_lru_reclaim++; > >> >> maxscan = min(target << 1, atomic_long_read(&cli->cl_lru_in_list)); > >> >> - while (!list_empty(&cli->cl_lru_list)) { > >> >> + list_for_each_entry_safe(opg, tmp, &cli->cl_lru_list, ops_lru) { > >> >> struct cl_page *page; > >> >> bool will_free = false; > >> >> > >> >> @@ -582,8 +583,6 @@ long osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, > >> >> if (--maxscan < 0) > >> >> break; > >> >> > >> >> - opg = list_entry(cli->cl_lru_list.next, struct osc_page, > >> >> - ops_lru); > >> >> page = opg->ops_cl.cpl_page; > >> >> if (lru_page_busy(cli, page)) { > >> >> list_move_tail(&opg->ops_lru, &cli->cl_lru_list); > >> >> @@ -1043,6 +1042,7 @@ unsigned long osc_cache_shrink_scan(struct shrinker *sk, > >> >> { > >> >> struct client_obd *stop_anchor = NULL; > >> >> struct client_obd *cli; > >> >> + struct client_obd *tmp; > >> >> struct lu_env *env; > >> >> long shrank = 0; > >> >> u16 refcheck; > >> >> @@ -1059,10 +1059,7 @@ unsigned long osc_cache_shrink_scan(struct shrinker *sk, > >> >> return SHRINK_STOP; > >> >> > >> >> spin_lock(&osc_shrink_lock); > >> >> - while (!list_empty(&osc_shrink_list)) { > >> >> - cli = list_entry(osc_shrink_list.next, struct client_obd, > >> >> - cl_shrink_list); > >> >> - > >> >> + list_for_each_entry_safe(cli, tmp, &osc_shrink_list, cl_shrink_list) { > >> >> if (!stop_anchor) > >> >> stop_anchor = cli; > >> >> else if (cli == stop_anchor) > >> >> -- > >> >> 2.7.4 > >> >> > >> >> -- > >> >> You received this message because you are subscribed to the Google Groups "outreachy-kernel" group. > >> >> To unsubscribe from this group and stop receiving emails from it, send an email to outreachy-kernel+unsubscribe at googlegroups.com. > >> >> To post to this group, send email to outreachy-kernel at googlegroups.com. > >> >> To view this discussion on the web visit https://groups.google.com/d/msgid/outreachy-kernel/1488733610-22289-6-git-send-email-singhalsimran0%40gmail.com. > >> >> For more options, visit https://groups.google.com/d/optout. > >> >> > >> > From jsimmons at infradead.org Mon Mar 6 15:20:49 2017 From: jsimmons at infradead.org (James Simmons) Date: Mon, 6 Mar 2017 15:20:49 +0000 (GMT) Subject: [lustre-devel] [PATCH 5/5] staging: lustre: osc_page.c: Use list_for_each_entry_safe In-Reply-To: <1488733610-22289-6-git-send-email-singhalsimran0@gmail.com> References: <1488733610-22289-1-git-send-email-singhalsimran0@gmail.com> <1488733610-22289-6-git-send-email-singhalsimran0@gmail.com> Message-ID: > Doubly linked lists which are iterated using list_empty > and list_entry macros have been replaced with list_for_each_entry_safe > macro. > This makes the iteration simpler and more readable. > > This patch replaces the while loop containing list_empty and list_entry > with list_for_each_entry_safe. > > This was done with Coccinelle. > > @@ > expression E1; > identifier I1, I2; > type T; > iterator name list_for_each_entry_safe; > @@ > > T *I1; > + T *tmp; > ... > - while (list_empty(&E1) == 0) > + list_for_each_entry_safe (I1, tmp, &E1, I2) > { > ...when != T *I1; > - I1 = list_entry(E1.next, T, I2); > ... > } > > Signed-off-by: simran singhal NAK!!!!!! This change was reverted in commit cd15dd6ef4ea11df87f717b8b1b83aaa738ec8af Doing these while (list_empty(..)) to list_for_entry... are not simple changes and have broken things in lustre before. Unless you really understand the state machine of the lustre code I don't recommend these kinds of change for lustre. > --- > drivers/staging/lustre/lustre/osc/osc_page.c | 11 ++++------- > 1 file changed, 4 insertions(+), 7 deletions(-) > > diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c > index ed8a0dc..e8b974f 100644 > --- a/drivers/staging/lustre/lustre/osc/osc_page.c > +++ b/drivers/staging/lustre/lustre/osc/osc_page.c > @@ -542,6 +542,7 @@ long osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, > struct cl_object *clobj = NULL; > struct cl_page **pvec; > struct osc_page *opg; > + struct osc_page *tmp; > int maxscan = 0; > long count = 0; > int index = 0; > @@ -572,7 +573,7 @@ long osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, > if (force) > cli->cl_lru_reclaim++; > maxscan = min(target << 1, atomic_long_read(&cli->cl_lru_in_list)); > - while (!list_empty(&cli->cl_lru_list)) { > + list_for_each_entry_safe(opg, tmp, &cli->cl_lru_list, ops_lru) { > struct cl_page *page; > bool will_free = false; > > @@ -582,8 +583,6 @@ long osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, > if (--maxscan < 0) > break; > > - opg = list_entry(cli->cl_lru_list.next, struct osc_page, > - ops_lru); > page = opg->ops_cl.cpl_page; > if (lru_page_busy(cli, page)) { > list_move_tail(&opg->ops_lru, &cli->cl_lru_list); > @@ -1043,6 +1042,7 @@ unsigned long osc_cache_shrink_scan(struct shrinker *sk, > { > struct client_obd *stop_anchor = NULL; > struct client_obd *cli; > + struct client_obd *tmp; > struct lu_env *env; > long shrank = 0; > u16 refcheck; > @@ -1059,10 +1059,7 @@ unsigned long osc_cache_shrink_scan(struct shrinker *sk, > return SHRINK_STOP; > > spin_lock(&osc_shrink_lock); > - while (!list_empty(&osc_shrink_list)) { > - cli = list_entry(osc_shrink_list.next, struct client_obd, > - cl_shrink_list); > - > + list_for_each_entry_safe(cli, tmp, &osc_shrink_list, cl_shrink_list) { > if (!stop_anchor) > stop_anchor = cli; > else if (cli == stop_anchor) > -- > 2.7.4 > > From paf at cray.com Mon Mar 6 16:25:39 2017 From: paf at cray.com (Patrick Farrell) Date: Mon, 6 Mar 2017 16:25:39 +0000 Subject: [lustre-devel] [PATCH 5/5] staging: lustre: osc_page.c: Use list_for_each_entry_safe In-Reply-To: References: <1488733610-22289-1-git-send-email-singhalsimran0@gmail.com> <1488733610-22289-6-git-send-email-singhalsimran0@gmail.com>, Message-ID: I would also dispute the logic in this particular Coccinelle script more generally. list_for_each_entry_safe and while(list_empty(&list) == 0) (or, more clearly, while(!list_empty(&list))) are NOT equivalent. Unless I've misunderstood the "for" loop used, that will run once for each item in the list, 'while' will run until the list is empty. They just aren't the same thing, and can't be swapped one for one in general. Sure, sometimes the usage is equivalent, but this coccinelle script can at most flag candidates for a change (which must be checked), it can't be used to just generate patches. - Patrick ________________________________ From: lustre-devel on behalf of James Simmons Sent: Monday, March 6, 2017 9:20:49 AM To: simran singhal Cc: devel at driverdev.osuosl.org; gregkh at linuxfoundation.org; linux-kernel at vger.kernel.org; oleg.drokin at intel.com; outreachy-kernel at googlegroups.com; lustre-devel at lists.lustre.org Subject: Re: [lustre-devel] [PATCH 5/5] staging: lustre: osc_page.c: Use list_for_each_entry_safe > Doubly linked lists which are iterated using list_empty > and list_entry macros have been replaced with list_for_each_entry_safe > macro. > This makes the iteration simpler and more readable. > > This patch replaces the while loop containing list_empty and list_entry > with list_for_each_entry_safe. > > This was done with Coccinelle. > > @@ > expression E1; > identifier I1, I2; > type T; > iterator name list_for_each_entry_safe; > @@ > > T *I1; > + T *tmp; > ... > - while (list_empty(&E1) == 0) > + list_for_each_entry_safe (I1, tmp, &E1, I2) > { > ...when != T *I1; > - I1 = list_entry(E1.next, T, I2); > ... > } > > Signed-off-by: simran singhal NAK!!!!!! This change was reverted in commit cd15dd6ef4ea11df87f717b8b1b83aaa738ec8af Doing these while (list_empty(..)) to list_for_entry... are not simple changes and have broken things in lustre before. Unless you really understand the state machine of the lustre code I don't recommend these kinds of change for lustre. > --- > drivers/staging/lustre/lustre/osc/osc_page.c | 11 ++++------- > 1 file changed, 4 insertions(+), 7 deletions(-) > > diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c > index ed8a0dc..e8b974f 100644 > --- a/drivers/staging/lustre/lustre/osc/osc_page.c > +++ b/drivers/staging/lustre/lustre/osc/osc_page.c > @@ -542,6 +542,7 @@ long osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, > struct cl_object *clobj = NULL; > struct cl_page **pvec; > struct osc_page *opg; > + struct osc_page *tmp; > int maxscan = 0; > long count = 0; > int index = 0; > @@ -572,7 +573,7 @@ long osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, > if (force) > cli->cl_lru_reclaim++; > maxscan = min(target << 1, atomic_long_read(&cli->cl_lru_in_list)); > - while (!list_empty(&cli->cl_lru_list)) { > + list_for_each_entry_safe(opg, tmp, &cli->cl_lru_list, ops_lru) { > struct cl_page *page; > bool will_free = false; > > @@ -582,8 +583,6 @@ long osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, > if (--maxscan < 0) > break; > > - opg = list_entry(cli->cl_lru_list.next, struct osc_page, > - ops_lru); > page = opg->ops_cl.cpl_page; > if (lru_page_busy(cli, page)) { > list_move_tail(&opg->ops_lru, &cli->cl_lru_list); > @@ -1043,6 +1042,7 @@ unsigned long osc_cache_shrink_scan(struct shrinker *sk, > { > struct client_obd *stop_anchor = NULL; > struct client_obd *cli; > + struct client_obd *tmp; > struct lu_env *env; > long shrank = 0; > u16 refcheck; > @@ -1059,10 +1059,7 @@ unsigned long osc_cache_shrink_scan(struct shrinker *sk, > return SHRINK_STOP; > > spin_lock(&osc_shrink_lock); > - while (!list_empty(&osc_shrink_list)) { > - cli = list_entry(osc_shrink_list.next, struct client_obd, > - cl_shrink_list); > - > + list_for_each_entry_safe(cli, tmp, &osc_shrink_list, cl_shrink_list) { > if (!stop_anchor) > stop_anchor = cli; > else if (cli == stop_anchor) > -- > 2.7.4 > > _______________________________________________ lustre-devel mailing list lustre-devel at lists.lustre.org http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org -------------- next part -------------- An HTML attachment was scrubbed... URL: From oleg.drokin at intel.com Tue Mar 7 05:38:16 2017 From: oleg.drokin at intel.com (Oleg Drokin) Date: Tue, 7 Mar 2017 00:38:16 -0500 Subject: [lustre-devel] [PATCH] staging: lustre: fix sparse warning about different address spaces In-Reply-To: <1488412629-20859-1-git-send-email-mario.bambagini@gmail.com> References: <1488412629-20859-1-git-send-email-mario.bambagini@gmail.com> Message-ID: On Mar 1, 2017, at 6:57 PM, Mario Bambagini wrote: > fixed the following sparse warning by adding proper cast: > drivers/staging//lustre/lustre/obdclass/obd_config.c:1055:74: warning: incorrect type in argument 2 (different address spaces) > drivers/staging//lustre/lustre/obdclass/obd_config.c:1055:74: expected char const [noderef] * > drivers/staging//lustre/lustre/obdclass/obd_config.c:1055:74: got char *[assigned] sval > > Signed-off-by: Mario Bambagini The patch is fine, but just be advised this whole function is going away real soon now per Al Viro request (and also because it no longer does what it should). > --- > drivers/staging/lustre/lustre/obdclass/obd_config.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/drivers/staging/lustre/lustre/obdclass/obd_config.c b/drivers/staging/lustre/lustre/obdclass/obd_config.c > index 9ca84c7..8fce88f 100644 > --- a/drivers/staging/lustre/lustre/obdclass/obd_config.c > +++ b/drivers/staging/lustre/lustre/obdclass/obd_config.c > @@ -1052,7 +1052,8 @@ int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars, > > oldfs = get_fs(); > set_fs(KERNEL_DS); > - rc = var->fops->write(&fakefile, sval, > + rc = var->fops->write(&fakefile, > + (const char __user *)sval, > vallen, NULL); > set_fs(oldfs); > } > -- > 2.1.4 > > _______________________________________________ > lustre-devel mailing list > lustre-devel at lists.lustre.org > http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org From oleg.drokin at intel.com Tue Mar 7 06:05:52 2017 From: oleg.drokin at intel.com (Oleg Drokin) Date: Tue, 7 Mar 2017 01:05:52 -0500 Subject: [lustre-devel] [PATCH 5/5] staging/lustre: Use generic range rwlock In-Reply-To: <1488863010-13028-6-git-send-email-dave@stgolabs.net> References: <1488863010-13028-1-git-send-email-dave@stgolabs.net> <1488863010-13028-6-git-send-email-dave@stgolabs.net> Message-ID: <512F521B-5FA2-4ED8-82F4-5CD90A381813@intel.com> On Mar 7, 2017, at 12:03 AM, Davidlohr Bueso wrote: > This replaces the in-house version, which is also derived > from Jan's interval tree implementation. > > Cc: oleg.drokin at intel.com > Cc: andreas.dilger at intel.com > Cc: jsimmons at infradead.org > Cc: lustre-devel at lists.lustre.org > > Signed-off-by: Davidlohr Bueso > --- > XXX: compile tested only. In house uses 'ulong long', generic uses 'ulong', is this a problem? Hm, cannot seem to find the other patches in this series anywhere to verify and my subscription to linux-kernel broke as it turns out. You mean the range is ulong? So only can have this working up to 2G offsets on the 32bit systems and then wrap around? > > drivers/staging/lustre/lustre/llite/Makefile | 2 +- > drivers/staging/lustre/lustre/llite/file.c | 21 +- > .../staging/lustre/lustre/llite/llite_internal.h | 4 +- > drivers/staging/lustre/lustre/llite/llite_lib.c | 3 +- > drivers/staging/lustre/lustre/llite/range_lock.c | 239 --------------------- > drivers/staging/lustre/lustre/llite/range_lock.h | 82 ------- > 6 files changed, 15 insertions(+), 336 deletions(-) > delete mode 100644 drivers/staging/lustre/lustre/llite/range_lock.c > delete mode 100644 drivers/staging/lustre/lustre/llite/range_lock.h > > diff --git a/drivers/staging/lustre/lustre/llite/Makefile b/drivers/staging/lustre/lustre/llite/Makefile > index 322d4fa63f5d..922a901bc62c 100644 > --- a/drivers/staging/lustre/lustre/llite/Makefile > +++ b/drivers/staging/lustre/lustre/llite/Makefile > @@ -1,6 +1,6 @@ > obj-$(CONFIG_LUSTRE_FS) += lustre.o > lustre-y := dcache.o dir.o file.o llite_lib.o llite_nfs.o \ > - rw.o rw26.o namei.o symlink.o llite_mmap.o range_lock.o \ > + rw.o rw26.o namei.o symlink.o llite_mmap.o \ > xattr.o xattr_cache.o xattr_security.o \ > super25.o statahead.o glimpse.o lcommon_cl.o lcommon_misc.o \ > vvp_dev.o vvp_page.o vvp_lock.o vvp_io.o vvp_object.o \ > diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c > index 481c0d01d4c6..1a14a79f87f8 100644 > --- a/drivers/staging/lustre/lustre/llite/file.c > +++ b/drivers/staging/lustre/lustre/llite/file.c > @@ -42,6 +42,7 @@ > #include > #include > #include > +#include > #include "../include/lustre/ll_fiemap.h" > #include "../include/lustre/lustre_ioctl.h" > #include "../include/lustre_swab.h" > @@ -1055,7 +1056,7 @@ ll_file_io_generic(const struct lu_env *env, struct vvp_io_args *args, > struct ll_inode_info *lli = ll_i2info(file_inode(file)); > struct ll_file_data *fd = LUSTRE_FPRIVATE(file); > struct vvp_io *vio = vvp_env_io(env); > - struct range_lock range; > + struct range_rwlock range; > struct cl_io *io; > ssize_t result = 0; > int rc = 0; > @@ -1072,9 +1073,9 @@ ll_file_io_generic(const struct lu_env *env, struct vvp_io_args *args, > bool range_locked = false; > > if (file->f_flags & O_APPEND) > - range_lock_init(&range, 0, LUSTRE_EOF); > + range_rwlock_init(&range, 0, LUSTRE_EOF); > else > - range_lock_init(&range, *ppos, *ppos + count - 1); > + range_rwlock_init(&range, *ppos, *ppos + count - 1); > > vio->vui_fd = LUSTRE_FPRIVATE(file); > vio->vui_iter = args->u.normal.via_iter; > @@ -1087,10 +1088,9 @@ ll_file_io_generic(const struct lu_env *env, struct vvp_io_args *args, > if (((iot == CIT_WRITE) || > (iot == CIT_READ && (file->f_flags & O_DIRECT))) && > !(vio->vui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) { > - CDEBUG(D_VFSTRACE, "Range lock [%llu, %llu]\n", > - range.rl_node.in_extent.start, > - range.rl_node.in_extent.end); > - rc = range_lock(&lli->lli_write_tree, &range); > + CDEBUG(D_VFSTRACE, "Range lock [%lu, %lu]\n", > + range.node.start, range.node.last); > + rc = range_write_lock_interruptible(&lli->lli_write_tree, &range); > if (rc < 0) > goto out; > > @@ -1100,10 +1100,9 @@ ll_file_io_generic(const struct lu_env *env, struct vvp_io_args *args, > rc = cl_io_loop(env, io); > ll_cl_remove(file, env); > if (range_locked) { > - CDEBUG(D_VFSTRACE, "Range unlock [%llu, %llu]\n", > - range.rl_node.in_extent.start, > - range.rl_node.in_extent.end); > - range_unlock(&lli->lli_write_tree, &range); > + CDEBUG(D_VFSTRACE, "Range unlock [%lu, %lu]\n", > + range.node.start, range.node.last); > + range_write_unlock(&lli->lli_write_tree, &range); > } > } else { > /* cl_io_rw_init() handled IO */ > diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h > index 55f68acd85d1..aa2ae72e3e70 100644 > --- a/drivers/staging/lustre/lustre/llite/llite_internal.h > +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h > @@ -49,8 +49,8 @@ > #include > #include > #include > +#include > #include "vvp_internal.h" > -#include "range_lock.h" > > #ifndef FMODE_EXEC > #define FMODE_EXEC 0 > @@ -193,7 +193,7 @@ struct ll_inode_info { > * } > */ > struct rw_semaphore lli_trunc_sem; > - struct range_lock_tree lli_write_tree; > + struct range_rwlock_tree lli_write_tree; > > struct rw_semaphore lli_glimpse_sem; > unsigned long lli_glimpse_time; > diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c > index b229cbc7bb33..8054e916b3f5 100644 > --- a/drivers/staging/lustre/lustre/llite/llite_lib.c > +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c > @@ -40,6 +40,7 @@ > #include > #include > #include > +#include > > #include "../include/lustre/lustre_ioctl.h" > #include "../include/lustre_ha.h" > @@ -853,7 +854,7 @@ void ll_lli_init(struct ll_inode_info *lli) > mutex_init(&lli->lli_size_mutex); > lli->lli_symlink_name = NULL; > init_rwsem(&lli->lli_trunc_sem); > - range_lock_tree_init(&lli->lli_write_tree); > + range_rwlock_tree_init(&lli->lli_write_tree); > init_rwsem(&lli->lli_glimpse_sem); > lli->lli_glimpse_time = 0; > INIT_LIST_HEAD(&lli->lli_agl_list); > diff --git a/drivers/staging/lustre/lustre/llite/range_lock.c b/drivers/staging/lustre/lustre/llite/range_lock.c > deleted file mode 100644 > index 14148a097476..000000000000 > --- a/drivers/staging/lustre/lustre/llite/range_lock.c > +++ /dev/null > @@ -1,239 +0,0 @@ > -/* > - * GPL HEADER START > - * > - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. > - * > - * This program is free software; you can redistribute it and/or modify > - * it under the terms of the GNU General Public License version 2 only, > - * as published by the Free Software Foundation. > - * > - * This program is distributed in the hope that it will be useful, but > - * WITHOUT ANY WARRANTY; without even the implied warranty of > - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > - * General Public License version 2 for more details (a copy is included > - * in the LICENSE file that accompanied this code). > - * > - * You should have received a copy of the GNU General Public License > - * version 2 along with this program; If not, see > - * http://www.gnu.org/licenses/gpl-2.0.html > - * > - * GPL HEADER END > - */ > -/* > - * Range lock is used to allow multiple threads writing a single shared > - * file given each thread is writing to a non-overlapping portion of the > - * file. > - * > - * Refer to the possible upstream kernel version of range lock by > - * Jan Kara : https://lkml.org/lkml/2013/1/31/480 > - * > - * This file could later replaced by the upstream kernel version. > - */ > -/* > - * Author: Prakash Surya > - * Author: Bobi Jam > - */ > -#include "range_lock.h" > -#include "../include/lustre/lustre_user.h" > - > -/** > - * Initialize a range lock tree > - * > - * \param tree [in] an empty range lock tree > - * > - * Pre: Caller should have allocated the range lock tree. > - * Post: The range lock tree is ready to function. > - */ > -void range_lock_tree_init(struct range_lock_tree *tree) > -{ > - tree->rlt_root = NULL; > - tree->rlt_sequence = 0; > - spin_lock_init(&tree->rlt_lock); > -} > - > -/** > - * Initialize a range lock node > - * > - * \param lock [in] an empty range lock node > - * \param start [in] start of the covering region > - * \param end [in] end of the covering region > - * > - * Pre: Caller should have allocated the range lock node. > - * Post: The range lock node is meant to cover [start, end] region > - */ > -int range_lock_init(struct range_lock *lock, __u64 start, __u64 end) > -{ > - int rc; > - > - memset(&lock->rl_node, 0, sizeof(lock->rl_node)); > - if (end != LUSTRE_EOF) > - end >>= PAGE_SHIFT; > - rc = interval_set(&lock->rl_node, start >> PAGE_SHIFT, end); > - if (rc) > - return rc; > - > - INIT_LIST_HEAD(&lock->rl_next_lock); > - lock->rl_task = NULL; > - lock->rl_lock_count = 0; > - lock->rl_blocking_ranges = 0; > - lock->rl_sequence = 0; > - return rc; > -} > - > -static inline struct range_lock *next_lock(struct range_lock *lock) > -{ > - return list_entry(lock->rl_next_lock.next, typeof(*lock), rl_next_lock); > -} > - > -/** > - * Helper function of range_unlock() > - * > - * \param node [in] a range lock found overlapped during interval node > - * search > - * \param arg [in] the range lock to be tested > - * > - * \retval INTERVAL_ITER_CONT indicate to continue the search for next > - * overlapping range node > - * \retval INTERVAL_ITER_STOP indicate to stop the search > - */ > -static enum interval_iter range_unlock_cb(struct interval_node *node, void *arg) > -{ > - struct range_lock *lock = arg; > - struct range_lock *overlap = node2rangelock(node); > - struct range_lock *iter; > - > - list_for_each_entry(iter, &overlap->rl_next_lock, rl_next_lock) { > - if (iter->rl_sequence > lock->rl_sequence) { > - --iter->rl_blocking_ranges; > - LASSERT(iter->rl_blocking_ranges > 0); > - } > - } > - if (overlap->rl_sequence > lock->rl_sequence) { > - --overlap->rl_blocking_ranges; > - if (overlap->rl_blocking_ranges == 0) > - wake_up_process(overlap->rl_task); > - } > - return INTERVAL_ITER_CONT; > -} > - > -/** > - * Unlock a range lock, wake up locks blocked by this lock. > - * > - * \param tree [in] range lock tree > - * \param lock [in] range lock to be deleted > - * > - * If this lock has been granted, relase it; if not, just delete it from > - * the tree or the same region lock list. Wake up those locks only blocked > - * by this lock through range_unlock_cb(). > - */ > -void range_unlock(struct range_lock_tree *tree, struct range_lock *lock) > -{ > - spin_lock(&tree->rlt_lock); > - if (!list_empty(&lock->rl_next_lock)) { > - struct range_lock *next; > - > - if (interval_is_intree(&lock->rl_node)) { /* first lock */ > - /* Insert the next same range lock into the tree */ > - next = next_lock(lock); > - next->rl_lock_count = lock->rl_lock_count - 1; > - interval_erase(&lock->rl_node, &tree->rlt_root); > - interval_insert(&next->rl_node, &tree->rlt_root); > - } else { > - /* find the first lock in tree */ > - list_for_each_entry(next, &lock->rl_next_lock, > - rl_next_lock) { > - if (!interval_is_intree(&next->rl_node)) > - continue; > - > - LASSERT(next->rl_lock_count > 0); > - next->rl_lock_count--; > - break; > - } > - } > - list_del_init(&lock->rl_next_lock); > - } else { > - LASSERT(interval_is_intree(&lock->rl_node)); > - interval_erase(&lock->rl_node, &tree->rlt_root); > - } > - > - interval_search(tree->rlt_root, &lock->rl_node.in_extent, > - range_unlock_cb, lock); > - spin_unlock(&tree->rlt_lock); > -} > - > -/** > - * Helper function of range_lock() > - * > - * \param node [in] a range lock found overlapped during interval node > - * search > - * \param arg [in] the range lock to be tested > - * > - * \retval INTERVAL_ITER_CONT indicate to continue the search for next > - * overlapping range node > - * \retval INTERVAL_ITER_STOP indicate to stop the search > - */ > -static enum interval_iter range_lock_cb(struct interval_node *node, void *arg) > -{ > - struct range_lock *lock = (struct range_lock *)arg; > - struct range_lock *overlap = node2rangelock(node); > - > - lock->rl_blocking_ranges += overlap->rl_lock_count + 1; > - return INTERVAL_ITER_CONT; > -} > - > -/** > - * Lock a region > - * > - * \param tree [in] range lock tree > - * \param lock [in] range lock node containing the region span > - * > - * \retval 0 get the range lock > - * \retval <0 error code while not getting the range lock > - * > - * If there exists overlapping range lock, the new lock will wait and > - * retry, if later it find that it is not the chosen one to wake up, > - * it wait again. > - */ > -int range_lock(struct range_lock_tree *tree, struct range_lock *lock) > -{ > - struct interval_node *node; > - int rc = 0; > - > - spin_lock(&tree->rlt_lock); > - /* > - * We need to check for all conflicting intervals > - * already in the tree. > - */ > - interval_search(tree->rlt_root, &lock->rl_node.in_extent, > - range_lock_cb, lock); > - /* > - * Insert to the tree if I am unique, otherwise I've been linked to > - * the rl_next_lock of another lock which has the same range as mine > - * in range_lock_cb(). > - */ > - node = interval_insert(&lock->rl_node, &tree->rlt_root); > - if (node) { > - struct range_lock *tmp = node2rangelock(node); > - > - list_add_tail(&lock->rl_next_lock, &tmp->rl_next_lock); > - tmp->rl_lock_count++; > - } > - lock->rl_sequence = ++tree->rlt_sequence; > - > - while (lock->rl_blocking_ranges > 0) { > - lock->rl_task = current; > - __set_current_state(TASK_INTERRUPTIBLE); > - spin_unlock(&tree->rlt_lock); > - schedule(); > - > - if (signal_pending(current)) { > - range_unlock(tree, lock); > - rc = -EINTR; > - goto out; > - } > - spin_lock(&tree->rlt_lock); > - } > - spin_unlock(&tree->rlt_lock); > -out: > - return rc; > -} > diff --git a/drivers/staging/lustre/lustre/llite/range_lock.h b/drivers/staging/lustre/lustre/llite/range_lock.h > deleted file mode 100644 > index 779091ccec4e..000000000000 > --- a/drivers/staging/lustre/lustre/llite/range_lock.h > +++ /dev/null > @@ -1,82 +0,0 @@ > -/* > - * GPL HEADER START > - * > - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. > - * > - * This program is free software; you can redistribute it and/or modify > - * it under the terms of the GNU General Public License version 2 only, > - * as published by the Free Software Foundation. > - * > - * This program is distributed in the hope that it will be useful, but > - * WITHOUT ANY WARRANTY; without even the implied warranty of > - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > - * General Public License version 2 for more details (a copy is included > - * in the LICENSE file that accompanied this code). > - * > - * You should have received a copy of the GNU General Public License > - * version 2 along with this program; If not, see > - * http://www.gnu.org/licenses/gpl-2.0.html > - * > - * GPL HEADER END > - */ > -/* > - * Range lock is used to allow multiple threads writing a single shared > - * file given each thread is writing to a non-overlapping portion of the > - * file. > - * > - * Refer to the possible upstream kernel version of range lock by > - * Jan Kara : https://lkml.org/lkml/2013/1/31/480 > - * > - * This file could later replaced by the upstream kernel version. > - */ > -/* > - * Author: Prakash Surya > - * Author: Bobi Jam > - */ > -#ifndef _RANGE_LOCK_H > -#define _RANGE_LOCK_H > - > -#include "../../include/linux/libcfs/libcfs.h" > -#include "../include/interval_tree.h" > - > -struct range_lock { > - struct interval_node rl_node; > - /** > - * Process to enqueue this lock. > - */ > - struct task_struct *rl_task; > - /** > - * List of locks with the same range. > - */ > - struct list_head rl_next_lock; > - /** > - * Number of locks in the list rl_next_lock > - */ > - unsigned int rl_lock_count; > - /** > - * Number of ranges which are blocking acquisition of the lock > - */ > - unsigned int rl_blocking_ranges; > - /** > - * Sequence number of range lock. This number is used to get to know > - * the order the locks are queued; this is required for range_cancel(). > - */ > - __u64 rl_sequence; > -}; > - > -static inline struct range_lock *node2rangelock(const struct interval_node *n) > -{ > - return container_of(n, struct range_lock, rl_node); > -} > - > -struct range_lock_tree { > - struct interval_node *rlt_root; > - spinlock_t rlt_lock; /* protect range lock tree */ > - __u64 rlt_sequence; > -}; > - > -void range_lock_tree_init(struct range_lock_tree *tree); > -int range_lock_init(struct range_lock *lock, __u64 start, __u64 end); > -int range_lock(struct range_lock_tree *tree, struct range_lock *lock); > -void range_unlock(struct range_lock_tree *tree, struct range_lock *lock); > -#endif > -- > 2.6.6 From andreas.dilger at intel.com Tue Mar 7 10:20:56 2017 From: andreas.dilger at intel.com (Dilger, Andreas) Date: Tue, 7 Mar 2017 10:20:56 +0000 Subject: [lustre-devel] [PATCH 5/5] staging: lustre: osc_page.c: Use list_for_each_entry_safe In-Reply-To: References: <1488733610-22289-1-git-send-email-singhalsimran0@gmail.com> <1488733610-22289-6-git-send-email-singhalsimran0@gmail.com> Message-ID: <64A47B25-17B2-4ED8-9066-6796E97768A0@intel.com> On Mar 6, 2017, at 08:20, James Simmons wrote: > >> >> Doubly linked lists which are iterated using list_empty >> and list_entry macros have been replaced with list_for_each_entry_safe >> macro. >> This makes the iteration simpler and more readable. >> >> This patch replaces the while loop containing list_empty and list_entry >> with list_for_each_entry_safe. >> >> This was done with Coccinelle. >> >> @@ >> expression E1; >> identifier I1, I2; >> type T; >> iterator name list_for_each_entry_safe; >> @@ >> >> T *I1; >> + T *tmp; >> ... >> - while (list_empty(&E1) == 0) >> + list_for_each_entry_safe (I1, tmp, &E1, I2) >> { >> ...when != T *I1; >> - I1 = list_entry(E1.next, T, I2); >> ... >> } >> >> Signed-off-by: simran singhal > > NAK!!!!!! > > This change was reverted in commit > > cd15dd6ef4ea11df87f717b8b1b83aaa738ec8af > > Doing these while (list_empty(..)) to list_for_entry... > are not simple changes and have broken things in lustre > before. Unless you really understand the state machine of > the lustre code I don't recommend these kinds of change > for lustre. It may be useful to add a comment to these cases where the while() loop cannot be replaced by list_for_each_entry_safe() (with details of why that is the case) to avoid such optimization attempts again in the future. Cheers, Andreas > >> --- >> drivers/staging/lustre/lustre/osc/osc_page.c | 11 ++++------- >> 1 file changed, 4 insertions(+), 7 deletions(-) >> >> diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c >> index ed8a0dc..e8b974f 100644 >> --- a/drivers/staging/lustre/lustre/osc/osc_page.c >> +++ b/drivers/staging/lustre/lustre/osc/osc_page.c >> @@ -542,6 +542,7 @@ long osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, >> struct cl_object *clobj = NULL; >> struct cl_page **pvec; >> struct osc_page *opg; >> + struct osc_page *tmp; >> int maxscan = 0; >> long count = 0; >> int index = 0; >> @@ -572,7 +573,7 @@ long osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, >> if (force) >> cli->cl_lru_reclaim++; >> maxscan = min(target << 1, atomic_long_read(&cli->cl_lru_in_list)); >> - while (!list_empty(&cli->cl_lru_list)) { >> + list_for_each_entry_safe(opg, tmp, &cli->cl_lru_list, ops_lru) { >> struct cl_page *page; >> bool will_free = false; >> >> @@ -582,8 +583,6 @@ long osc_lru_shrink(const struct lu_env *env, struct client_obd *cli, >> if (--maxscan < 0) >> break; >> >> - opg = list_entry(cli->cl_lru_list.next, struct osc_page, >> - ops_lru); >> page = opg->ops_cl.cpl_page; >> if (lru_page_busy(cli, page)) { >> list_move_tail(&opg->ops_lru, &cli->cl_lru_list); >> @@ -1043,6 +1042,7 @@ unsigned long osc_cache_shrink_scan(struct shrinker *sk, >> { >> struct client_obd *stop_anchor = NULL; >> struct client_obd *cli; >> + struct client_obd *tmp; >> struct lu_env *env; >> long shrank = 0; >> u16 refcheck; >> @@ -1059,10 +1059,7 @@ unsigned long osc_cache_shrink_scan(struct shrinker *sk, >> return SHRINK_STOP; >> >> spin_lock(&osc_shrink_lock); >> - while (!list_empty(&osc_shrink_list)) { >> - cli = list_entry(osc_shrink_list.next, struct client_obd, >> - cl_shrink_list); >> - >> + list_for_each_entry_safe(cli, tmp, &osc_shrink_list, cl_shrink_list) { >> if (!stop_anchor) >> stop_anchor = cli; >> else if (cli == stop_anchor) >> -- >> 2.7.4 Cheers, Andreas -- Andreas Dilger Lustre Principal Architect Intel Corporation From lkp at intel.com Thu Mar 9 08:56:19 2017 From: lkp at intel.com (kbuild test robot) Date: Thu, 9 Mar 2017 16:56:19 +0800 Subject: [lustre-devel] [PATCH 5/5] staging/lustre: Use generic range rwlock In-Reply-To: <1488863010-13028-6-git-send-email-dave@stgolabs.net> Message-ID: <201703091601.TR7uxISO%fengguang.wu@intel.com> Hi Davidlohr, [auto build test WARNING on staging/staging-testing] [also build test WARNING on v4.11-rc1 next-20170309] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Davidlohr-Bueso/locking-Introduce-range-reader-writer-lock/20170309-140444 config: i386-allmodconfig (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=i386 All warnings (new ones prefixed by >>): In file included from drivers/staging/lustre/lustre/llite/../include/lustre/lustre_idl.h:76:0, from drivers/staging/lustre/lustre/llite/../include/lustre_lib.h:49, from drivers/staging/lustre/lustre/llite/../include/lustre_dlm.h:47, from drivers/staging/lustre/lustre/llite/file.c:40: drivers/staging/lustre/lustre/llite/file.c: In function 'll_file_io_generic': >> drivers/staging/lustre/lustre/llite/../include/lustre/lustre_user.h:78:20: warning: large integer implicitly truncated to unsigned type [-Woverflow] #define LUSTRE_EOF 0xffffffffffffffffULL ^ >> drivers/staging/lustre/lustre/llite/file.c:1072:33: note: in expansion of macro 'LUSTRE_EOF' range_rwlock_init(&range, 0, LUSTRE_EOF); ^~~~~~~~~~ vim +78 drivers/staging/lustre/lustre/llite/../include/lustre/lustre_user.h 23ec6607e9 John L. Hammond 2016-09-18 62 * are co-existing. 23ec6607e9 John L. Hammond 2016-09-18 63 */ 23ec6607e9 John L. Hammond 2016-09-18 64 #if __BITS_PER_LONG != 64 || defined(__ARCH_WANT_STAT64) 23ec6607e9 John L. Hammond 2016-09-18 65 typedef struct stat64 lstat_t; 23ec6607e9 John L. Hammond 2016-09-18 66 #define lstat_f lstat64 f0cf21abcc John L. Hammond 2016-10-02 67 #define fstat_f fstat64 f0cf21abcc John L. Hammond 2016-10-02 68 #define fstatat_f fstatat64 23ec6607e9 John L. Hammond 2016-09-18 69 #else 23ec6607e9 John L. Hammond 2016-09-18 70 typedef struct stat lstat_t; 23ec6607e9 John L. Hammond 2016-09-18 71 #define lstat_f lstat f0cf21abcc John L. Hammond 2016-10-02 72 #define fstat_f fstat f0cf21abcc John L. Hammond 2016-10-02 73 #define fstatat_f fstatat 23ec6607e9 John L. Hammond 2016-09-18 74 #endif 23ec6607e9 John L. Hammond 2016-09-18 75 23ec6607e9 John L. Hammond 2016-09-18 76 #define HAVE_LOV_USER_MDS_DATA d7e09d0397 Peng Tao 2013-05-02 77 00c0a6aea0 John L. Hammond 2016-08-16 @78 #define LUSTRE_EOF 0xffffffffffffffffULL 00c0a6aea0 John L. Hammond 2016-08-16 79 d7e09d0397 Peng Tao 2013-05-02 80 /* for statfs() */ d7e09d0397 Peng Tao 2013-05-02 81 #define LL_SUPER_MAGIC 0x0BD00BD0 d7e09d0397 Peng Tao 2013-05-02 82 d7e09d0397 Peng Tao 2013-05-02 83 #ifndef FSFILT_IOC_GETFLAGS d7e09d0397 Peng Tao 2013-05-02 84 #define FSFILT_IOC_GETFLAGS _IOR('f', 1, long) d7e09d0397 Peng Tao 2013-05-02 85 #define FSFILT_IOC_SETFLAGS _IOW('f', 2, long) d7e09d0397 Peng Tao 2013-05-02 86 #define FSFILT_IOC_GETVERSION _IOR('f', 3, long) :::::: The code at line 78 was first introduced by commit :::::: 00c0a6aea0d0ab2c11594616244d787ad7bf64dc staging: lustre: uapi: reduce scope of lustre_idl.h :::::: TO: John L. Hammond :::::: CC: Greg Kroah-Hartman --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation -------------- next part -------------- A non-text attachment was scrubbed... Name: .config.gz Type: application/gzip Size: 59084 bytes Desc: not available URL: From gregkh at linuxfoundation.org Thu Mar 9 12:08:50 2017 From: gregkh at linuxfoundation.org (Greg Kroah-Hartman) Date: Thu, 9 Mar 2017 13:08:50 +0100 Subject: [lustre-devel] [PATCH] Minor Fix to please checkpatch Declaring 'unsigned int' instead of 'unsigned' In-Reply-To: <1489060251-22958-1-git-send-email-pushkar.iit@gmail.com> References: <1489060251-22958-1-git-send-email-pushkar.iit@gmail.com> Message-ID: <20170309120850.GA13054@kroah.com> On Thu, Mar 09, 2017 at 05:20:51PM +0530, Pushkar Jambhlekar wrote: > Signed-off-by: Pushkar Jambhlekar > --- > drivers/staging/lustre/lustre/llite/vvp_dev.c | 9 ++++----- > 1 file changed, 4 insertions(+), 5 deletions(-) Hi, This is the friendly patch-bot of Greg Kroah-Hartman. You have sent him a patch that has triggered this response. He used to manually respond to these common problems, but in order to save his sanity (he kept writing the same thing over and over, yet to different people), I was created. Hopefully you will not take offence and will fix the problem in your patch and resubmit it so that it can be accepted into the Linux kernel tree. You are receiving this message because of the following common error(s) as indicated below: - You did not specify a description of why the patch is needed, or possibly, any description at all, in the email body. Please read the section entitled "The canonical patch format" in the kernel file, Documentation/SubmittingPatches for what is needed in order to properly describe the change. - You did not write a descriptive Subject: for the patch, allowing Greg, and everyone else, to know what this patch is all about. Please read the section entitled "The canonical patch format" in the kernel file, Documentation/SubmittingPatches for what a proper Subject: line should look like. If you wish to discuss this problem further, or you have questions about how to resolve this issue, please feel free to respond to this email and Greg will reply once he has dug out from the pending patches received from other developers. thanks, greg k-h's patch email bot From gregkh at linuxfoundation.org Thu Mar 9 13:15:35 2017 From: gregkh at linuxfoundation.org (Greg Kroah-Hartman) Date: Thu, 9 Mar 2017 14:15:35 +0100 Subject: [lustre-devel] [PATCH] Minor coding guideline Fix in lusture module In-Reply-To: <1489062127-23258-1-git-send-email-pushkar.iit@gmail.com> References: <1489062127-23258-1-git-send-email-pushkar.iit@gmail.com> Message-ID: <20170309131535.GB2908@kroah.com> On Thu, Mar 09, 2017 at 05:52:07PM +0530, Pushkar Jambhlekar wrote: > Replacing 'unsigned' with 'unsigned int' in vvp_pgcache_id. > Checkpath.pl passed. > > Signed-off-by: Pushkar Jambhlekar > --- > drivers/staging/lustre/lustre/llite/vvp_dev.c | 9 ++++----- > 1 file changed, 4 insertions(+), 5 deletions(-) > > diff --git a/drivers/staging/lustre/lustre/llite/vvp_dev.c b/drivers/staging/lustre/lustre/llite/vvp_dev.c > index 12c129f7e..8d78755 100644 > --- a/drivers/staging/lustre/lustre/llite/vvp_dev.c > +++ b/drivers/staging/lustre/lustre/llite/vvp_dev.c > @@ -381,11 +381,10 @@ int cl_sb_fini(struct super_block *sb) > #define PGC_DEPTH_SHIFT (32) > > struct vvp_pgcache_id { > - unsigned vpi_bucket; > - unsigned vpi_depth; > - uint32_t vpi_index; > - > - unsigned vpi_curdep; > + unsigned int vpi_bucket; > + unsigned int vpi_depth; > + uint32_t vpi_index; > + unsigned int vpi_curdep; > struct lu_object_header *vpi_obj; > }; > > -- > 2.7.4 Hi, This is the friendly patch-bot of Greg Kroah-Hartman. You have sent him a patch that has triggered this response. He used to manually respond to these common problems, but in order to save his sanity (he kept writing the same thing over and over, yet to different people), I was created. Hopefully you will not take offence and will fix the problem in your patch and resubmit it so that it can be accepted into the Linux kernel tree. You are receiving this message because of the following common error(s) as indicated below: - You did not specify a description of why the patch is needed, or possibly, any description at all, in the email body. Please read the section entitled "The canonical patch format" in the kernel file, Documentation/SubmittingPatches for what is needed in order to properly describe the change. - You did not write a descriptive Subject: for the patch, allowing Greg, and everyone else, to know what this patch is all about. Please read the section entitled "The canonical patch format" in the kernel file, Documentation/SubmittingPatches for what a proper Subject: line should look like. If you wish to discuss this problem further, or you have questions about how to resolve this issue, please feel free to respond to this email and Greg will reply once he has dug out from the pending patches received from other developers. thanks, greg k-h's patch email bot From lkp at intel.com Thu Mar 9 14:40:53 2017 From: lkp at intel.com (kbuild test robot) Date: Thu, 9 Mar 2017 22:40:53 +0800 Subject: [lustre-devel] [PATCH 5/5] staging/lustre: Use generic range rwlock In-Reply-To: <1488863010-13028-6-git-send-email-dave@stgolabs.net> Message-ID: <201703092251.IuWrdxhU%fengguang.wu@intel.com> Hi Davidlohr, [auto build test WARNING on staging/staging-testing] [also build test WARNING on v4.11-rc1 next-20170309] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Davidlohr-Bueso/locking-Introduce-range-reader-writer-lock/20170309-140444 config: i386-randconfig-i1-201710 (attached as .config) compiler: gcc-4.8 (Debian 4.8.4-1) 4.8.4 reproduce: # save the attached .config to linux build tree make ARCH=i386 All warnings (new ones prefixed by >>): drivers/staging/lustre/lustre/llite/file.c: In function 'll_file_io_generic': >> drivers/staging/lustre/lustre/llite/file.c:1072:4: warning: large integer implicitly truncated to unsigned type [-Woverflow] range_rwlock_init(&range, 0, LUSTRE_EOF); ^ vim +1072 drivers/staging/lustre/lustre/llite/file.c 1056 struct cl_io *io; 1057 ssize_t result = 0; 1058 int rc = 0; 1059 1060 CDEBUG(D_VFSTRACE, "file: %pD, type: %d ppos: %llu, count: %zu\n", 1061 file, iot, *ppos, count); 1062 1063 restart: 1064 io = vvp_env_thread_io(env); 1065 ll_io_init(io, file, iot == CIT_WRITE); 1066 1067 if (cl_io_rw_init(env, io, iot, *ppos, count) == 0) { 1068 struct vvp_io *vio = vvp_env_io(env); 1069 bool range_locked = false; 1070 1071 if (file->f_flags & O_APPEND) > 1072 range_rwlock_init(&range, 0, LUSTRE_EOF); 1073 else 1074 range_rwlock_init(&range, *ppos, *ppos + count - 1); 1075 1076 vio->vui_fd = LUSTRE_FPRIVATE(file); 1077 vio->vui_iter = args->u.normal.via_iter; 1078 vio->vui_iocb = args->u.normal.via_iocb; 1079 /* 1080 * Direct IO reads must also take range lock, --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation -------------- next part -------------- A non-text attachment was scrubbed... Name: .config.gz Type: application/gzip Size: 37254 bytes Desc: not available URL: From andreas.dilger at intel.com Fri Mar 10 05:25:22 2017 From: andreas.dilger at intel.com (Dilger, Andreas) Date: Fri, 10 Mar 2017 05:25:22 +0000 Subject: [lustre-devel] [PATCH] Minor coding guideline Fix in lusture module In-Reply-To: <1489062127-23258-1-git-send-email-pushkar.iit@gmail.com> References: <1489062127-23258-1-git-send-email-pushkar.iit@gmail.com> Message-ID: On Mar 9, 2017, at 05:22, Pushkar Jambhlekar wrote: > Subject: Minor coding guideline Fix in lusture module I suspect the patchbot is unhappy with the subject line not containing anything useful, and not containing the subsystem name. Something like: staging/lustre/llite: replace "unsigned" with "unsigned int" > Replacing 'unsigned' with 'unsigned int' in vvp_pgcache_id. Remove double space, and reference function names like vvp_pgcache_id(). > Checkpath.pl passed. "checkpatch.pl" Cheers, Andreas > Signed-off-by: Pushkar Jambhlekar > --- > drivers/staging/lustre/lustre/llite/vvp_dev.c | 9 ++++----- > 1 file changed, 4 insertions(+), 5 deletions(-) > > diff --git a/drivers/staging/lustre/lustre/llite/vvp_dev.c b/drivers/staging/lustre/lustre/llite/vvp_dev.c > index 12c129f7e..8d78755 100644 > --- a/drivers/staging/lustre/lustre/llite/vvp_dev.c > +++ b/drivers/staging/lustre/lustre/llite/vvp_dev.c > @@ -381,11 +381,10 @@ int cl_sb_fini(struct super_block *sb) > #define PGC_DEPTH_SHIFT (32) > > struct vvp_pgcache_id { > - unsigned vpi_bucket; > - unsigned vpi_depth; > - uint32_t vpi_index; > - > - unsigned vpi_curdep; > + unsigned int vpi_bucket; > + unsigned int vpi_depth; > + uint32_t vpi_index; > + unsigned int vpi_curdep; > struct lu_object_header *vpi_obj; > }; > > -- > 2.7.4 > Cheers, Andreas -- Andreas Dilger Lustre Principal Architect Intel Corporation From Craig at craiginches.com Sat Mar 11 13:07:40 2017 From: Craig at craiginches.com (Craig Inches) Date: Sat, 11 Mar 2017 13:07:40 +0000 Subject: [lustre-devel] [PATCH] staging: lustre fix constant comparision style issue in lu_object.h Message-ID: <20170311130740.11488-1-Craig@craiginches.com> This patch resolves the "Comparisons should place the constant on the right side of the test" found with checkpatch tool. Signed-off-by: Craig Inches --- drivers/staging/lustre/lustre/include/lu_object.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/include/lu_object.h b/drivers/staging/lustre/lustre/include/lu_object.h index 7a4f412..02be805 100644 --- a/drivers/staging/lustre/lustre/include/lu_object.h +++ b/drivers/staging/lustre/lustre/include/lu_object.h @@ -1130,7 +1130,7 @@ struct lu_context_key { { \ type *value; \ \ - BUILD_BUG_ON(PAGE_SIZE < sizeof(*value)); \ + BUILD_BUG_ON(sizeof(*value) > PAGE_SIZE); \ \ value = kzalloc(sizeof(*value), GFP_NOFS); \ if (!value) \ -- 2.10.2 From gregkh at linuxfoundation.org Sun Mar 12 13:36:47 2017 From: gregkh at linuxfoundation.org (Greg Kroah-Hartman) Date: Sun, 12 Mar 2017 14:36:47 +0100 Subject: [lustre-devel] [PATCH] staging: lustre: replace simple_strtoul with kstrtoint In-Reply-To: <20170309145300.GA2849@gentoo> References: <20170309145300.GA2849@gentoo> Message-ID: <20170312133647.GB27791@kroah.com> On Thu, Mar 09, 2017 at 03:53:00PM +0100, Marcin Ciupak wrote: > Replace simple_strtoul with kstrtoint. Why? > simple_strtoul is marked for obsoletion. > > Signed-off-by: Marcin Ciupak > --- > drivers/staging/lustre/lustre/obdclass/obd_mount.c | 20 ++++++++++++++++---- > 1 file changed, 16 insertions(+), 4 deletions(-) > > diff --git a/drivers/staging/lustre/lustre/obdclass/obd_mount.c b/drivers/staging/lustre/lustre/obdclass/obd_mount.c > index 8e0d4b1d86dc..4a604e9b3e49 100644 > --- a/drivers/staging/lustre/lustre/obdclass/obd_mount.c > +++ b/drivers/staging/lustre/lustre/obdclass/obd_mount.c > @@ -924,12 +924,24 @@ static int lmd_parse(char *options, struct lustre_mount_data *lmd) > lmd->lmd_flags |= LMD_FLG_ABORT_RECOV; > clear++; > } else if (strncmp(s1, "recovery_time_soft=", 19) == 0) { > - lmd->lmd_recovery_time_soft = max_t(int, > - simple_strtoul(s1 + 19, NULL, 10), time_min); > + int res; > + > + rc = kstrtoint(s1 + 19, 10, &res); > + if (rc) > + lmd->lmd_recovery_time_soft = time_min; > + else > + lmd->lmd_recovery_time_soft = max_t(int, res, > + time_min); Are you sure this is correct? Do you really want to use max_t()? Why is time_min used if there is an error? Can't this all be written a lot simpler to actually make it semi-sane? thanks, greg k-h From gregkh at linuxfoundation.org Sun Mar 12 13:37:22 2017 From: gregkh at linuxfoundation.org (Greg KH) Date: Sun, 12 Mar 2017 14:37:22 +0100 Subject: [lustre-devel] [PATCH] staging: lustre fix constant comparision style issue in lu_object.h In-Reply-To: <20170311130740.11488-1-Craig@craiginches.com> References: <20170311130740.11488-1-Craig@craiginches.com> Message-ID: <20170312133722.GC27791@kroah.com> On Sat, Mar 11, 2017 at 01:07:40PM +0000, Craig Inches wrote: > This patch resolves the "Comparisons should place the constant on > the right side of the test" found with checkpatch tool. Both are constants, I think checkpatch is the thing that is wrong here, don't you agree? thanks, greg k-h From Craig at craiginches.com Sun Mar 12 19:18:40 2017 From: Craig at craiginches.com (Craig Inches) Date: Sun, 12 Mar 2017 19:18:40 +0000 Subject: [lustre-devel] [PATCH] staging: lustre shorten multiple lines over 80 char in lu_object.h Message-ID: <20170312191840.20981-1-Craig@craiginches.com> This patch adjusts lines so that they are less than 80 char. Checkpatch.pl idenitified the issue. Signed-off-by: Craig Inches --- drivers/staging/lustre/lustre/include/lu_object.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/lu_object.h b/drivers/staging/lustre/lustre/include/lu_object.h index 7a4f412..73ecc23 100644 --- a/drivers/staging/lustre/lustre/include/lu_object.h +++ b/drivers/staging/lustre/lustre/include/lu_object.h @@ -147,9 +147,9 @@ struct lu_device_operations { struct lu_device *); /** - * initialize local objects for device. this method called after layer has - * been initialized (after LCFG_SETUP stage) and before it starts serving - * user requests. + * initialize local objects for device. this method called after layer + * has been initialized (after LCFG_SETUP stage) and before it starts + * serving user requests. */ int (*ldo_prepare)(const struct lu_env *, @@ -791,7 +791,7 @@ int lu_cdebug_printer(const struct lu_env *env, #define LU_OBJECT_DEBUG(mask, env, object, format, ...) \ do { \ if (cfs_cdebug_show(mask, DEBUG_SUBSYSTEM)) { \ - LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, mask, NULL); \ + LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, mask, NULL); \ lu_object_print(env, &msgdata, lu_cdebug_printer, object);\ CDEBUG(mask, format "\n", ## __VA_ARGS__); \ } \ @@ -803,7 +803,7 @@ do { \ #define LU_OBJECT_HEADER(mask, env, object, format, ...) \ do { \ if (cfs_cdebug_show(mask, DEBUG_SUBSYSTEM)) { \ - LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, mask, NULL); \ + LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, mask, NULL); \ lu_object_header_print(env, &msgdata, lu_cdebug_printer,\ (object)->lo_header); \ lu_cdebug_printer(env, &msgdata, "\n"); \ -- 2.10.2 From dan.carpenter at oracle.com Mon Mar 13 12:11:10 2017 From: dan.carpenter at oracle.com (Dan Carpenter) Date: Mon, 13 Mar 2017 15:11:10 +0300 Subject: [lustre-devel] [PATCH] staging: lustre fix constant comparision style issue in lu_object.h In-Reply-To: <20170312133722.GC27791@kroah.com> References: <20170311130740.11488-1-Craig@craiginches.com> <20170312133722.GC27791@kroah.com> Message-ID: <20170313121110.GD4136@mwanda> On Sun, Mar 12, 2017 at 02:37:22PM +0100, Greg KH wrote: > On Sat, Mar 11, 2017 at 01:07:40PM +0000, Craig Inches wrote: > > This patch resolves the "Comparisons should place the constant on > > the right side of the test" found with checkpatch tool. > > Both are constants, I think checkpatch is the thing that is wrong here, > don't you agree? Sort of constant-ish... The sizeof(*value) changes each time the macro is used. I feel like checkpatch is right. regads, dan carpenter From craig at craiginches.com Mon Mar 13 13:13:51 2017 From: craig at craiginches.com (Craig Inches) Date: Mon, 13 Mar 2017 13:13:51 +0000 Subject: [lustre-devel] [PATCH] staging: lustre fix constant comparision style issue in lu_object.h In-Reply-To: <20170313121110.GD4136@mwanda> References: <20170311130740.11488-1-Craig@craiginches.com> <20170312133722.GC27791@kroah.com> <20170313121110.GD4136@mwanda> Message-ID: <20170313131351.GA14108@starbase.xayto.local> On Mon, Mar 13, 2017 at 03:11:10PM +0300, Dan Carpenter wrote: > On Sun, Mar 12, 2017 at 02:37:22PM +0100, Greg KH wrote: > > On Sat, Mar 11, 2017 at 01:07:40PM +0000, Craig Inches wrote: > > > This patch resolves the "Comparisons should place the constant on > > > the right side of the test" found with checkpatch tool. > > > > Both are constants, I think checkpatch is the thing that is wrong here, > > don't you agree? > > Sort of constant-ish... The sizeof(*value) changes each time the macro > is used. I feel like checkpatch is right. > > regads, > dan carpenter > That was my take aswell.. PAGE_SIZE is constant for each boot, but sizeof could change. Happy to be lead by the more experienced here though. Cheers Craig From oleg.drokin at intel.com Mon Mar 13 17:51:41 2017 From: oleg.drokin at intel.com (Oleg Drokin) Date: Mon, 13 Mar 2017 13:51:41 -0400 Subject: [lustre-devel] new tag 2.9.54 Message-ID: <1D1A49D3-B135-4FBF-A043-2416B838B3C6@intel.com> Hello! I just tagged 2.9.54 tag in Lustre master development tree. Here's the changelog: Alex Zhuravlev (1): LU-8686 osd: add few more credits if debugging is enabled Alexander Boyko (1): LU-8947 test: fix getting OST name at sanity test_253 Andreas Dilger (4): LU-5969 lustreapi: allow "version" without "lustre:" LU-8139 ofd: allow brw_size with 'M' suffix LU-8582 tests: skip sanity test_255a for interop LU-9024 tests: improve conf-sanity test_63 output Andrew Perepechko (1): LU-9127 target: tgt_cb_last_committed is too noisy Arnd Bergmann (3): LU-4423 mdc: use 64-bit timestamps for mdc LU-4423 llite: use 64-bit times in another debug print LU-4423 llite: use 64-bit llite debugfs timestamps Ben Evans (1): LU-7670 mdt: allow changelog commands to return errors Bob Glossman (1): LU-9101 kernel: kernel update [SLES11 SP4 3.0.101-94] Bobi Jam (1): LU-8773 llite: refactor lov_object_fiemap() Bruno Faccini (3): LU-8526 tests: ensure all OSTs active for allocations LU-6499 obdclass: obdclass module cleanup upon load error LU-9038 obdclass: handle early requests vs CT registering Dmitry Eremin (2): LU-8888 clio: remove unused members from struct cl_thread_info LU-8703 libcfs: remove usless abstraction Fan Yong (2): LU-9040 scrub: handle group boundary properly LU-8900 snapshot: new config for MDT write barrier Giuseppe Di Natale (2): LU-9100 lnet: lctl net down success when lnet not loaded LU-9098 lnet: Move lnet_routes.conf to /etc Gu Zheng (1): LU-9116 libcfs: avoid overflow of crypto bandwidth caculation Hongchao Zhang (1): LU-9059 utils: skip label check for client Jadhav Vikram (1): LU-8788 tests: modify create_pool to use as wrapper James Nunez (1): LU-9125 test: Correct setstripe -s option James Shimek (1): LU-8734 gnilnd: Handle dla credits exhaustion James Simmons (7): LU-6142 lnet: remove most of typedefs from LNet headers LU-8066 ldlm: move server side /proc/fs/lustre/ldlm to sysfs LU-8560 build: announce linux kernel 4.6.7 support LU-9019 mdt: use 64-bit timestamps for rename stats LU-9019 obd: use 64-bit timestamps for rpc stats LU-9067 utils: ensure debugfs is mounted LU-9118 o2iblnd: handle MOFED libcfs time api collision John L. Hammond (5): LU-9123 test: correct setstripe options in layout test LU-8403 obd: remove OBD_NOTIFY_SYNC{,_NONBLOCK} LU-9109 ldlm: restore missing newlines in ldlm sysfs files LU-8403 obd: remove OBD_NOTIFY_CONFIG LU-8827 mdt: bypass quota enforcement for HSM release Lai Siyao (2): LU-8981 test: sanity 311 check is too strict LU-7994 statahead: add smp_mb() to serialize ops Li Xi (3): LU-8550 test: fix problems of conf-sanity test_32 LU-7441 nrs: Free hash table if failed to start a nrs policy LU-8726 osd-ldiskfs: bypass read for benchmarking Minh Diep (1): LU-8642 build: suppport building various OFED Nathaniel Clark (1): LU-8934 spec: Use correct provides in lustre-dkms Niu Yawei (3): LU-9081 config: don't attach sub logs for LWP LU-9115 llite: buggy special handling on MULTIMODRPCS LU-9132 utils: tuning max_sectors_kb on mount Oleg Drokin (2): LU-9125 utils: Postpone deprecation of some options. New tag 2.9.54 Parinay Kondekar (1): LU-9103 tests: SKIP recovery-small/110g for old MDS versions Quentin Bouget (1): LU-8911 tests: sanity-hsm test_24d fails on a local setup Sergey Cheremencev (3): LU-9094 o2iblnd: reconnect peer for REJ_INVALID_SERVICE_ID LU-9094 lnet: remove ni from lnet_finalize LU-9094 o2iblnd: kill timedout txs from ibp_tx_queue Steve Guminski (4): LU-6210 utils: Change positional struct initializers to C99 LU-5170 utils: Add support for --list-commands option LU-8767 llite: Improve proc file text in lproc_llite.c LU-6210 mdd: Change positional struct initializers to C99 Yang Sheng (1): LU-9146 ldiskfs: backport a few patches to resolve deadlock From green at linuxhacker.ru Sat Mar 18 06:24:08 2017 From: green at linuxhacker.ru (Oleg Drokin) Date: Sat, 18 Mar 2017 02:24:08 -0400 Subject: [lustre-devel] [PATCH/RFC] staging/lustre: Rework class_process_proc_param Message-ID: <20170318062408.3207381-1-green@linuxhacker.ru> Ever since sysfs migration, class_process_proc_param stopped working correctly as all the useful params were no longer present as lvars. Replace all the nasty fake proc writes with hopefully less nasty kobject attribute search and then update the attributes as needed. Signed-off-by: Oleg Drokin Reported-by: Al Viro --- Al has quite rightfully complained in the past that class_process_proc_param is a terrible piece of code and needs to go. This patch is an attempt at improving it somewhat and in process drop all the user/kernel address space games we needed to play to make it work in the past (and which I suspect attracted Al's attention in the first place). Now I wonder if iterating kobject attributes like that would be ok with you Greg, or do you think there is a better way? class_find_write_attr could be turned into something generic since it's certainly convenient to reuse same table of name-write_method pairs, but I did some cursory research and nobody else seems to need anything of the sort in-tree. I know ll_process_config is still awful and I will likely just replace the current hack with kset_find_obj, but I just wanted to make sure this new approach would be ok before spending too much time on it. Thanks! drivers/staging/lustre/lustre/include/obd_class.h | 4 +- drivers/staging/lustre/lustre/llite/llite_lib.c | 10 +-- drivers/staging/lustre/lustre/lov/lov_obd.c | 3 +- drivers/staging/lustre/lustre/mdc/mdc_request.c | 3 +- .../staging/lustre/lustre/obdclass/obd_config.c | 78 ++++++++++------------ drivers/staging/lustre/lustre/osc/osc_request.c | 3 +- 6 files changed, 44 insertions(+), 57 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/obd_class.h b/drivers/staging/lustre/lustre/include/obd_class.h index 083a6ff..badafb8 100644 --- a/drivers/staging/lustre/lustre/include/obd_class.h +++ b/drivers/staging/lustre/lustre/include/obd_class.h @@ -114,8 +114,8 @@ typedef int (*llog_cb_t)(const struct lu_env *, struct llog_handle *, struct llog_rec_hdr *, void *); /* obd_config.c */ int class_process_config(struct lustre_cfg *lcfg); -int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars, - struct lustre_cfg *lcfg, void *data); +int class_process_attr_param(char *prefix, struct kobject *kobj, + struct lustre_cfg *lcfg); struct obd_device *class_incref(struct obd_device *obd, const char *scope, const void *source); void class_decref(struct obd_device *obd, diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index 7b80040..192b877 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -2259,7 +2259,7 @@ int ll_obd_statfs(struct inode *inode, void __user *arg) int ll_process_config(struct lustre_cfg *lcfg) { char *ptr; - void *sb; + struct super_block *sb; struct lprocfs_static_vars lvars; unsigned long x; int rc = 0; @@ -2273,15 +2273,15 @@ int ll_process_config(struct lustre_cfg *lcfg) rc = kstrtoul(ptr, 16, &x); if (rc != 0) return -EINVAL; - sb = (void *)x; + sb = (struct super_block *)x; /* This better be a real Lustre superblock! */ - LASSERT(s2lsi((struct super_block *)sb)->lsi_lmd->lmd_magic == LMD_MAGIC); + LASSERT(s2lsi(sb)->lsi_lmd->lmd_magic == LMD_MAGIC); /* Note we have not called client_common_fill_super yet, so * proc fns must be able to handle that! */ - rc = class_process_proc_param(PARAM_LLITE, lvars.obd_vars, - lcfg, sb); + rc = class_process_attr_param(PARAM_LLITE, &ll_s2sbi(sb)->ll_kobj, + lcfg); if (rc > 0) rc = 0; return rc; diff --git a/drivers/staging/lustre/lustre/lov/lov_obd.c b/drivers/staging/lustre/lustre/lov/lov_obd.c index b3161fb..c33a327 100644 --- a/drivers/staging/lustre/lustre/lov/lov_obd.c +++ b/drivers/staging/lustre/lustre/lov/lov_obd.c @@ -926,8 +926,7 @@ int lov_process_config_base(struct obd_device *obd, struct lustre_cfg *lcfg, lprocfs_lov_init_vars(&lvars); - rc = class_process_proc_param(PARAM_LOV, lvars.obd_vars, - lcfg, obd); + rc = class_process_attr_param(PARAM_LOV, &obd->obd_kobj, lcfg); if (rc > 0) rc = 0; goto out; diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c index 6bc2fb8..00387b8 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_request.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c @@ -2670,8 +2670,7 @@ static int mdc_process_config(struct obd_device *obd, u32 len, void *buf) lprocfs_mdc_init_vars(&lvars); switch (lcfg->lcfg_command) { default: - rc = class_process_proc_param(PARAM_MDC, lvars.obd_vars, - lcfg, obd); + rc = class_process_attr_param(PARAM_MDC, &obd->obd_kobj, lcfg); if (rc > 0) rc = 0; break; diff --git a/drivers/staging/lustre/lustre/obdclass/obd_config.c b/drivers/staging/lustre/lustre/obdclass/obd_config.c index 8fce88f..08fd126 100644 --- a/drivers/staging/lustre/lustre/obdclass/obd_config.c +++ b/drivers/staging/lustre/lustre/obdclass/obd_config.c @@ -995,26 +995,42 @@ int class_process_config(struct lustre_cfg *lcfg) } EXPORT_SYMBOL(class_process_config); -int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars, - struct lustre_cfg *lcfg, void *data) +static int class_find_write_attr(struct kobject *kobj, char *name, int namelen, + char *val, int vallen) +{ + struct attribute *attr; + struct kobj_type *kt = get_ktype(kobj); + int i; + + /* Empty object? */ + if (!kt || !kt->default_attrs) + return -ENOENT; + + for (i = 0; (attr = kt->default_attrs[i]) != NULL; i++) { + if (!strncmp(attr->name, name, namelen) && + namelen == strlen(attr->name)) { + if (kt->sysfs_ops && kt->sysfs_ops->store) + return kt->sysfs_ops->store(kobj, attr, val, + vallen); + return -EINVAL; + } + } + + return -ENOENT; +} + +int class_process_attr_param(char *prefix, struct kobject *kobj, + struct lustre_cfg *lcfg) { - struct lprocfs_vars *var; - struct file fakefile; - struct seq_file fake_seqfile; char *key, *sval; int i, keylen, vallen; - int matched = 0, j = 0; int rc = 0; - int skip = 0; if (lcfg->lcfg_command != LCFG_PARAM) { CERROR("Unknown command: %d\n", lcfg->lcfg_command); return -EINVAL; } - /* fake a seq file so that var->fops->write can work... */ - fakefile.private_data = &fake_seqfile; - fake_seqfile.private = data; /* e.g. tunefs.lustre --param mdt.group_upcall=foo /r/tmp/lustre-mdt * or lctl conf_param lustre-MDT0000.mdt.group_upcall=bar * or lctl conf_param lustre-OST0000.osc.max_dirty_mb=36 @@ -1038,39 +1054,16 @@ int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars, keylen = sval - key; sval++; vallen = strlen(sval); - matched = 0; - j = 0; - /* Search proc entries */ - while (lvars[j].name) { - var = &lvars[j]; - if (!class_match_param(key, var->name, NULL) && - keylen == strlen(var->name)) { - matched++; - rc = -EROFS; - if (var->fops && var->fops->write) { - mm_segment_t oldfs; - - oldfs = get_fs(); - set_fs(KERNEL_DS); - rc = var->fops->write(&fakefile, - (const char __user *)sval, - vallen, NULL); - set_fs(oldfs); - } - break; - } - j++; - } - if (!matched) { + rc = class_find_write_attr(kobj, key, keylen, sval, vallen); + + if (rc == -ENOENT) { CERROR("%.*s: %s unknown param %s\n", (int)strlen(prefix) - 1, prefix, (char *)lustre_cfg_string(lcfg, 0), key); /* rc = -EINVAL; continue parsing other params */ - skip++; } else if (rc < 0) { - CERROR("%s: error writing proc entry '%s': rc = %d\n", - prefix, var->name, rc); - rc = 0; + CERROR("%s: error writing proc entry '%.*s': rc = %d\n", + prefix, keylen, key, rc); } else { CDEBUG(D_CONFIG, "%s.%.*s: Set parameter %.*s=%s\n", lustre_cfg_string(lcfg, 0), @@ -1079,13 +1072,10 @@ int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars, } } - if (rc > 0) - rc = 0; - if (!rc && skip) - rc = skip; - return rc; + /* Even if we did not find anything to write to, keep processing */ + return 0; } -EXPORT_SYMBOL(class_process_proc_param); +EXPORT_SYMBOL(class_process_attr_param); /** Parse a configuration llog, doing various manipulations on them * for various reasons, (modifications for compatibility, skip obsolete diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c index d8aa3fb..158fb98 100644 --- a/drivers/staging/lustre/lustre/osc/osc_request.c +++ b/drivers/staging/lustre/lustre/osc/osc_request.c @@ -2773,8 +2773,7 @@ int osc_process_config_base(struct obd_device *obd, struct lustre_cfg *lcfg) switch (lcfg->lcfg_command) { default: - rc = class_process_proc_param(PARAM_OSC, lvars.obd_vars, - lcfg, obd); + rc = class_process_attr_param(PARAM_OSC, &obd->obd_kobj, lcfg); if (rc > 0) rc = 0; break; -- 2.9.3 From gregkh at linuxfoundation.org Sat Mar 18 10:34:43 2017 From: gregkh at linuxfoundation.org (Greg Kroah-Hartman) Date: Sat, 18 Mar 2017 18:34:43 +0800 Subject: [lustre-devel] [PATCH/RFC] staging/lustre: Rework class_process_proc_param In-Reply-To: <20170318062408.3207381-1-green@linuxhacker.ru> References: <20170318062408.3207381-1-green@linuxhacker.ru> Message-ID: <20170318103443.GA21943@kroah.com> On Sat, Mar 18, 2017 at 02:24:08AM -0400, Oleg Drokin wrote: > Ever since sysfs migration, class_process_proc_param stopped working > correctly as all the useful params were no longer present as lvars. > Replace all the nasty fake proc writes with hopefully less nasty > kobject attribute search and then update the attributes as needed. > > Signed-off-by: Oleg Drokin > Reported-by: Al Viro > --- > Al has quite rightfully complained in the past that class_process_proc_param > is a terrible piece of code and needs to go. > This patch is an attempt at improving it somewhat and in process drop > all the user/kernel address space games we needed to play to make it work > in the past (and which I suspect attracted Al's attention in the first place). > > Now I wonder if iterating kobject attributes like that would be ok with > you Greg, or do you think there is a better way? > class_find_write_attr could be turned into something generic since it's > certainly convenient to reuse same table of name-write_method pairs, > but I did some cursory research and nobody else seems to need anything > of the sort in-tree. > > I know ll_process_config is still awful and I will likely just > replace the current hack with kset_find_obj, but I just wanted to make > sure this new approach would be ok before spending too much time on it. I'm not quite sure what exactly you are even trying to do here. What is this interface? Who calls it, and how? What does it want to do? You can look up attributes for a kobject easily in the show/store functions (and some drivers just have a generic one and then you look at the string to see which attribute you are wanting to reference.) But you seem to be working backwards here, why do you have to look up a kobject? What is wrong with the "normal" way to interact with kobject attributes from sysfs? What does your "process proc" function do? Where does it get called from? totally confused, greg k-h From green at linuxhacker.ru Sat Mar 18 15:17:55 2017 From: green at linuxhacker.ru (Oleg Drokin) Date: Sat, 18 Mar 2017 11:17:55 -0400 Subject: [lustre-devel] [PATCH/RFC] staging/lustre: Rework class_process_proc_param In-Reply-To: <20170318103443.GA21943@kroah.com> References: <20170318062408.3207381-1-green@linuxhacker.ru> <20170318103443.GA21943@kroah.com> Message-ID: <9C67F0F2-005F-4D70-8320-9255625CB543@linuxhacker.ru> On Mar 18, 2017, at 6:34 AM, Greg Kroah-Hartman wrote: > On Sat, Mar 18, 2017 at 02:24:08AM -0400, Oleg Drokin wrote: >> Ever since sysfs migration, class_process_proc_param stopped working >> correctly as all the useful params were no longer present as lvars. >> Replace all the nasty fake proc writes with hopefully less nasty >> kobject attribute search and then update the attributes as needed. >> >> Signed-off-by: Oleg Drokin >> Reported-by: Al Viro >> --- >> Al has quite rightfully complained in the past that class_process_proc_param >> is a terrible piece of code and needs to go. >> This patch is an attempt at improving it somewhat and in process drop >> all the user/kernel address space games we needed to play to make it work >> in the past (and which I suspect attracted Al's attention in the first place). >> >> Now I wonder if iterating kobject attributes like that would be ok with >> you Greg, or do you think there is a better way? >> class_find_write_attr could be turned into something generic since it's >> certainly convenient to reuse same table of name-write_method pairs, >> but I did some cursory research and nobody else seems to need anything >> of the sort in-tree. >> >> I know ll_process_config is still awful and I will likely just >> replace the current hack with kset_find_obj, but I just wanted to make >> sure this new approach would be ok before spending too much time on it. > > I'm not quite sure what exactly you are even trying to do here. What is > this interface? Who calls it, and how? What does it want to do? This is a configuration client code. Management server has ability to pass down config information in the form of: fsname.subsystem.attribute=value to clients and other servers (subsystem determines if it's something of interest of clients or servers or both). This could be changed in the real time - i.e. you update it on the server and that gets propagated to all the clients/servers, so no need to ssh into every node to manually apply those changes and worry about client restarts (the config is remembered at the management server and would be applied to any new nodes connecting/across server restarts and such). So the way it then works then is once the string fsname.subsystem.attribute=value is delivered to the client, we find all instances of filesystem with fsname and then all subsystems within it (one kobject per subsystem instance) and then update the attributes to the value supplied. The same filesystem might be mounted more than once and then some layers might have multiple instances inside a single filesystems. In the end it would turn something like lustre.osc.max_dirty_mb=128 into writes to /sys/fs/lustre/osc/lustre-OST0000-osc-ffff8800d75ca000/max_dirty_mb and /sys/fs/lustre/osc/lustre-OST0001-osc-ffff8800d75ca000/max_dirty_mb without actually iterating in sysfs namespace. The alternative we considered is we can probably just do an upcall and have a userspace tool called with the parameter verbatim and try to figure it out, but that seems a lot less ideal, and also we'll get a bunch of complications from containers and such too, I imagine. The function pre-this patch is assuming that all these values are part of a list of procfs values (no longer true after sysfs migration) so just iterates that list and calls the write for matched names (but also needs to supply a userspace buffer so looks much uglier too). Hopefully this makes at least some sense. > You can look up attributes for a kobject easily in the show/store > functions (and some drivers just have a generic one and then you look at > the string to see which attribute you are wanting to reference.) But > you seem to be working backwards here, why do you have to look up a > kobject? But that leads to the need to list attribute names essentially twice: once for the attributes list, once in the show/set function to figure out how to deal with that name. > What is wrong with the "normal" way to interact with kobject attributes > from sysfs? > > What does your "process proc" function do? Where does it get called > from? > > totally confused, > > greg k-h From gregkh at linuxfoundation.org Sun Mar 19 04:29:39 2017 From: gregkh at linuxfoundation.org (Greg Kroah-Hartman) Date: Sun, 19 Mar 2017 12:29:39 +0800 Subject: [lustre-devel] [PATCH/RFC] staging/lustre: Rework class_process_proc_param In-Reply-To: <9C67F0F2-005F-4D70-8320-9255625CB543@linuxhacker.ru> References: <20170318062408.3207381-1-green@linuxhacker.ru> <20170318103443.GA21943@kroah.com> <9C67F0F2-005F-4D70-8320-9255625CB543@linuxhacker.ru> Message-ID: <20170319042939.GA32423@kroah.com> On Sat, Mar 18, 2017 at 11:17:55AM -0400, Oleg Drokin wrote: > > On Mar 18, 2017, at 6:34 AM, Greg Kroah-Hartman wrote: > > > On Sat, Mar 18, 2017 at 02:24:08AM -0400, Oleg Drokin wrote: > >> Ever since sysfs migration, class_process_proc_param stopped working > >> correctly as all the useful params were no longer present as lvars. > >> Replace all the nasty fake proc writes with hopefully less nasty > >> kobject attribute search and then update the attributes as needed. > >> > >> Signed-off-by: Oleg Drokin > >> Reported-by: Al Viro > >> --- > >> Al has quite rightfully complained in the past that class_process_proc_param > >> is a terrible piece of code and needs to go. > >> This patch is an attempt at improving it somewhat and in process drop > >> all the user/kernel address space games we needed to play to make it work > >> in the past (and which I suspect attracted Al's attention in the first place). > >> > >> Now I wonder if iterating kobject attributes like that would be ok with > >> you Greg, or do you think there is a better way? > >> class_find_write_attr could be turned into something generic since it's > >> certainly convenient to reuse same table of name-write_method pairs, > >> but I did some cursory research and nobody else seems to need anything > >> of the sort in-tree. > >> > >> I know ll_process_config is still awful and I will likely just > >> replace the current hack with kset_find_obj, but I just wanted to make > >> sure this new approach would be ok before spending too much time on it. > > > > I'm not quite sure what exactly you are even trying to do here. What is > > this interface? Who calls it, and how? What does it want to do? > > This is a configuration client code. > Management server has ability to pass down config information in the form of: > fsname.subsystem.attribute=value to clients and other servers > (subsystem determines if it's something of interest of clients or servers or > both). > This could be changed in the real time - i.e. you update it on the server and > that gets propagated to all the clients/servers, so no need to ssh into > every node to manually apply those changes and worry about client restarts > (the config is remembered at the management server and would be applied to any > new nodes connecting/across server restarts and such). > > So the way it then works then is once the string fsname.subsystem.attribute=value is delivered to the client, we find all instances of filesystem with fsname and then > all subsystems within it (one kobject per subsystem instance) and then update the > attributes to the value supplied. > > The same filesystem might be mounted more than once and then some layers might have > multiple instances inside a single filesystems. > > In the end it would turn something like lustre.osc.max_dirty_mb=128 into > writes to > /sys/fs/lustre/osc/lustre-OST0000-osc-ffff8800d75ca000/max_dirty_mb and > /sys/fs/lustre/osc/lustre-OST0001-osc-ffff8800d75ca000/max_dirty_mb > without actually iterating in sysfs namespace. Wait, who is doing the "write"? From within the kernel? Or some userspace app? I'm guessing from within the kernel, you are receiving the data from some other transport within the filesystem and then need to apply the settings? > The alternative we considered is we can probably just do an upcall and have > a userspace tool called with the parameter verbatim and try to figure it out, > but that seems a lot less ideal, and also we'll get a bunch of complications from > containers and such too, I imagine. Yeah, no, don't do an upcall, that's a mess. > The function pre-this patch is assuming that all these values are part of > a list of procfs values (no longer true after sysfs migration) so just iterates > that list and calls the write for matched names (but also needs to supply a userspace > buffer so looks much uglier too). For kobjects, you don't need userspace buffers, so this should be easier. > Hopefully this makes at least some sense. Yes, a bit more, but ugh, what a mess :) > > You can look up attributes for a kobject easily in the show/store > > functions (and some drivers just have a generic one and then you look at > > the string to see which attribute you are wanting to reference.) But > > you seem to be working backwards here, why do you have to look up a > > kobject? > > But that leads to the need to list attribute names essentially twice: > once for the attributes list, once in the show/set function to figure > out how to deal with that name. Yes, you don't need/want to do that. Let me go review the code now with that info, thanks, it makes more sense. greg k-h From green at linuxhacker.ru Sun Mar 19 04:41:20 2017 From: green at linuxhacker.ru (Oleg Drokin) Date: Sun, 19 Mar 2017 00:41:20 -0400 Subject: [lustre-devel] [PATCH/RFC] staging/lustre: Rework class_process_proc_param In-Reply-To: <20170319042939.GA32423@kroah.com> References: <20170318062408.3207381-1-green@linuxhacker.ru> <20170318103443.GA21943@kroah.com> <9C67F0F2-005F-4D70-8320-9255625CB543@linuxhacker.ru> <20170319042939.GA32423@kroah.com> Message-ID: On Mar 19, 2017, at 12:29 AM, Greg Kroah-Hartman wrote: > On Sat, Mar 18, 2017 at 11:17:55AM -0400, Oleg Drokin wrote: >> >> On Mar 18, 2017, at 6:34 AM, Greg Kroah-Hartman wrote: >> >>> On Sat, Mar 18, 2017 at 02:24:08AM -0400, Oleg Drokin wrote: >>>> Ever since sysfs migration, class_process_proc_param stopped working >>>> correctly as all the useful params were no longer present as lvars. >>>> Replace all the nasty fake proc writes with hopefully less nasty >>>> kobject attribute search and then update the attributes as needed. >>>> >>>> Signed-off-by: Oleg Drokin >>>> Reported-by: Al Viro >>>> --- >>>> Al has quite rightfully complained in the past that class_process_proc_param >>>> is a terrible piece of code and needs to go. >>>> This patch is an attempt at improving it somewhat and in process drop >>>> all the user/kernel address space games we needed to play to make it work >>>> in the past (and which I suspect attracted Al's attention in the first place). >>>> >>>> Now I wonder if iterating kobject attributes like that would be ok with >>>> you Greg, or do you think there is a better way? >>>> class_find_write_attr could be turned into something generic since it's >>>> certainly convenient to reuse same table of name-write_method pairs, >>>> but I did some cursory research and nobody else seems to need anything >>>> of the sort in-tree. >>>> >>>> I know ll_process_config is still awful and I will likely just >>>> replace the current hack with kset_find_obj, but I just wanted to make >>>> sure this new approach would be ok before spending too much time on it. >>> >>> I'm not quite sure what exactly you are even trying to do here. What is >>> this interface? Who calls it, and how? What does it want to do? >> >> This is a configuration client code. >> Management server has ability to pass down config information in the form of: >> fsname.subsystem.attribute=value to clients and other servers >> (subsystem determines if it's something of interest of clients or servers or >> both). >> This could be changed in the real time - i.e. you update it on the server and >> that gets propagated to all the clients/servers, so no need to ssh into >> every node to manually apply those changes and worry about client restarts >> (the config is remembered at the management server and would be applied to any >> new nodes connecting/across server restarts and such). >> >> So the way it then works then is once the string fsname.subsystem.attribute=value is delivered to the client, we find all instances of filesystem with fsname and then >> all subsystems within it (one kobject per subsystem instance) and then update the >> attributes to the value supplied. >> >> The same filesystem might be mounted more than once and then some layers might have >> multiple instances inside a single filesystems. >> >> In the end it would turn something like lustre.osc.max_dirty_mb=128 into >> writes to >> /sys/fs/lustre/osc/lustre-OST0000-osc-ffff8800d75ca000/max_dirty_mb and >> /sys/fs/lustre/osc/lustre-OST0001-osc-ffff8800d75ca000/max_dirty_mb >> without actually iterating in sysfs namespace. > > Wait, who is doing the "write"? From within the kernel? Or some > userspace app? I'm guessing from within the kernel, you are receiving > the data from some other transport within the filesystem and then need > to apply the settings? Yes, kernel code gets the notification "hey, there's a config change, come get it", then it requests the diff in the config and does the "write' by updating the attributes. >> The alternative we considered is we can probably just do an upcall and have >> a userspace tool called with the parameter verbatim and try to figure it out, >> but that seems a lot less ideal, and also we'll get a bunch of complications from >> containers and such too, I imagine. > > Yeah, no, don't do an upcall, that's a mess. > >> The function pre-this patch is assuming that all these values are part of >> a list of procfs values (no longer true after sysfs migration) so just iterates >> that list and calls the write for matched names (but also needs to supply a userspace >> buffer so looks much uglier too). > > For kobjects, you don't need userspace buffers, so this should be > easier. Right, it's less of a mess due to that. >> Hopefully this makes at least some sense. > > Yes, a bit more, but ugh, what a mess :) Overall big systems are quite messy in many ways no matter what you do, so it's always a case of pick your poison. >>> You can look up attributes for a kobject easily in the show/store >>> functions (and some drivers just have a generic one and then you look at >>> the string to see which attribute you are wanting to reference.) But >>> you seem to be working backwards here, why do you have to look up a >>> kobject? >> >> But that leads to the need to list attribute names essentially twice: >> once for the attributes list, once in the show/set function to figure >> out how to deal with that name. > > Yes, you don't need/want to do that. > > Let me go review the code now with that info, thanks, it makes more > sense. Thanks! In the end if the approach is mostly acceptable, I imagine if we just register the kobject for the config changes, we can do away with the individual layers calling the class_process_attr_param and instead have the class_process_config() call it directly more or less. From gregkh at linuxfoundation.org Sun Mar 19 04:41:47 2017 From: gregkh at linuxfoundation.org (Greg Kroah-Hartman) Date: Sun, 19 Mar 2017 12:41:47 +0800 Subject: [lustre-devel] [PATCH/RFC] staging/lustre: Rework class_process_proc_param In-Reply-To: <20170318062408.3207381-1-green@linuxhacker.ru> References: <20170318062408.3207381-1-green@linuxhacker.ru> Message-ID: <20170319044147.GA931@kroah.com> On Sat, Mar 18, 2017 at 02:24:08AM -0400, Oleg Drokin wrote: > Ever since sysfs migration, class_process_proc_param stopped working > correctly as all the useful params were no longer present as lvars. > Replace all the nasty fake proc writes with hopefully less nasty > kobject attribute search and then update the attributes as needed. > > Signed-off-by: Oleg Drokin > Reported-by: Al Viro > --- > Al has quite rightfully complained in the past that class_process_proc_param > is a terrible piece of code and needs to go. > This patch is an attempt at improving it somewhat and in process drop > all the user/kernel address space games we needed to play to make it work > in the past (and which I suspect attracted Al's attention in the first place). > > Now I wonder if iterating kobject attributes like that would be ok with > you Greg, or do you think there is a better way? > class_find_write_attr could be turned into something generic since it's > certainly convenient to reuse same table of name-write_method pairs, > but I did some cursory research and nobody else seems to need anything > of the sort in-tree. > > I know ll_process_config is still awful and I will likely just > replace the current hack with kset_find_obj, but I just wanted to make > sure this new approach would be ok before spending too much time on it. > > Thanks! > > drivers/staging/lustre/lustre/include/obd_class.h | 4 +- > drivers/staging/lustre/lustre/llite/llite_lib.c | 10 +-- > drivers/staging/lustre/lustre/lov/lov_obd.c | 3 +- > drivers/staging/lustre/lustre/mdc/mdc_request.c | 3 +- > .../staging/lustre/lustre/obdclass/obd_config.c | 78 ++++++++++------------ > drivers/staging/lustre/lustre/osc/osc_request.c | 3 +- > 6 files changed, 44 insertions(+), 57 deletions(-) > > diff --git a/drivers/staging/lustre/lustre/include/obd_class.h b/drivers/staging/lustre/lustre/include/obd_class.h > index 083a6ff..badafb8 100644 > --- a/drivers/staging/lustre/lustre/include/obd_class.h > +++ b/drivers/staging/lustre/lustre/include/obd_class.h > @@ -114,8 +114,8 @@ typedef int (*llog_cb_t)(const struct lu_env *, struct llog_handle *, > struct llog_rec_hdr *, void *); > /* obd_config.c */ > int class_process_config(struct lustre_cfg *lcfg); > -int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars, > - struct lustre_cfg *lcfg, void *data); > +int class_process_attr_param(char *prefix, struct kobject *kobj, > + struct lustre_cfg *lcfg); As you are exporting these functions, they will need to end up with a lustre_* prefix eventually :) > struct obd_device *class_incref(struct obd_device *obd, > const char *scope, const void *source); > void class_decref(struct obd_device *obd, > diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c > index 7b80040..192b877 100644 > --- a/drivers/staging/lustre/lustre/llite/llite_lib.c > +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c > @@ -2259,7 +2259,7 @@ int ll_obd_statfs(struct inode *inode, void __user *arg) > int ll_process_config(struct lustre_cfg *lcfg) > { > char *ptr; > - void *sb; > + struct super_block *sb; > struct lprocfs_static_vars lvars; > unsigned long x; > int rc = 0; > @@ -2273,15 +2273,15 @@ int ll_process_config(struct lustre_cfg *lcfg) > rc = kstrtoul(ptr, 16, &x); > if (rc != 0) > return -EINVAL; > - sb = (void *)x; > + sb = (struct super_block *)x; > /* This better be a real Lustre superblock! */ > - LASSERT(s2lsi((struct super_block *)sb)->lsi_lmd->lmd_magic == LMD_MAGIC); > + LASSERT(s2lsi(sb)->lsi_lmd->lmd_magic == LMD_MAGIC); > > /* Note we have not called client_common_fill_super yet, so > * proc fns must be able to handle that! > */ > - rc = class_process_proc_param(PARAM_LLITE, lvars.obd_vars, > - lcfg, sb); > + rc = class_process_attr_param(PARAM_LLITE, &ll_s2sbi(sb)->ll_kobj, > + lcfg); > if (rc > 0) > rc = 0; > return rc; > diff --git a/drivers/staging/lustre/lustre/lov/lov_obd.c b/drivers/staging/lustre/lustre/lov/lov_obd.c > index b3161fb..c33a327 100644 > --- a/drivers/staging/lustre/lustre/lov/lov_obd.c > +++ b/drivers/staging/lustre/lustre/lov/lov_obd.c > @@ -926,8 +926,7 @@ int lov_process_config_base(struct obd_device *obd, struct lustre_cfg *lcfg, > > lprocfs_lov_init_vars(&lvars); > > - rc = class_process_proc_param(PARAM_LOV, lvars.obd_vars, > - lcfg, obd); > + rc = class_process_attr_param(PARAM_LOV, &obd->obd_kobj, lcfg); > if (rc > 0) > rc = 0; > goto out; > diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c > index 6bc2fb8..00387b8 100644 > --- a/drivers/staging/lustre/lustre/mdc/mdc_request.c > +++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c > @@ -2670,8 +2670,7 @@ static int mdc_process_config(struct obd_device *obd, u32 len, void *buf) > lprocfs_mdc_init_vars(&lvars); > switch (lcfg->lcfg_command) { > default: > - rc = class_process_proc_param(PARAM_MDC, lvars.obd_vars, > - lcfg, obd); > + rc = class_process_attr_param(PARAM_MDC, &obd->obd_kobj, lcfg); > if (rc > 0) > rc = 0; > break; > diff --git a/drivers/staging/lustre/lustre/obdclass/obd_config.c b/drivers/staging/lustre/lustre/obdclass/obd_config.c > index 8fce88f..08fd126 100644 > --- a/drivers/staging/lustre/lustre/obdclass/obd_config.c > +++ b/drivers/staging/lustre/lustre/obdclass/obd_config.c > @@ -995,26 +995,42 @@ int class_process_config(struct lustre_cfg *lcfg) > } > EXPORT_SYMBOL(class_process_config); > > -int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars, > - struct lustre_cfg *lcfg, void *data) > +static int class_find_write_attr(struct kobject *kobj, char *name, int namelen, > + char *val, int vallen) > +{ > + struct attribute *attr; > + struct kobj_type *kt = get_ktype(kobj); > + int i; > + > + /* Empty object? */ > + if (!kt || !kt->default_attrs) > + return -ENOENT; > + > + for (i = 0; (attr = kt->default_attrs[i]) != NULL; i++) { > + if (!strncmp(attr->name, name, namelen) && > + namelen == strlen(attr->name)) { Why do you care about namelen? Why can't you just do a "normal" strcmp()? Is this "untrusted" user data? > + if (kt->sysfs_ops && kt->sysfs_ops->store) > + return kt->sysfs_ops->store(kobj, attr, val, > + vallen); > + return -EINVAL; > + } > + } > + > + return -ENOENT; > +} > + > +int class_process_attr_param(char *prefix, struct kobject *kobj, > + struct lustre_cfg *lcfg) > { > - struct lprocfs_vars *var; > - struct file fakefile; > - struct seq_file fake_seqfile; > char *key, *sval; > int i, keylen, vallen; > - int matched = 0, j = 0; > int rc = 0; > - int skip = 0; > > if (lcfg->lcfg_command != LCFG_PARAM) { > CERROR("Unknown command: %d\n", lcfg->lcfg_command); > return -EINVAL; > } > > - /* fake a seq file so that var->fops->write can work... */ > - fakefile.private_data = &fake_seqfile; > - fake_seqfile.private = data; > /* e.g. tunefs.lustre --param mdt.group_upcall=foo /r/tmp/lustre-mdt > * or lctl conf_param lustre-MDT0000.mdt.group_upcall=bar > * or lctl conf_param lustre-OST0000.osc.max_dirty_mb=36 > @@ -1038,39 +1054,16 @@ int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars, > keylen = sval - key; > sval++; > vallen = strlen(sval); > - matched = 0; > - j = 0; > - /* Search proc entries */ > - while (lvars[j].name) { > - var = &lvars[j]; > - if (!class_match_param(key, var->name, NULL) && > - keylen == strlen(var->name)) { > - matched++; > - rc = -EROFS; > - if (var->fops && var->fops->write) { > - mm_segment_t oldfs; > - > - oldfs = get_fs(); > - set_fs(KERNEL_DS); > - rc = var->fops->write(&fakefile, > - (const char __user *)sval, > - vallen, NULL); > - set_fs(oldfs); > - } > - break; > - } > - j++; > - } > - if (!matched) { > + rc = class_find_write_attr(kobj, key, keylen, sval, vallen); > + > + if (rc == -ENOENT) { > CERROR("%.*s: %s unknown param %s\n", > (int)strlen(prefix) - 1, prefix, > (char *)lustre_cfg_string(lcfg, 0), key); > /* rc = -EINVAL; continue parsing other params */ > - skip++; > } else if (rc < 0) { > - CERROR("%s: error writing proc entry '%s': rc = %d\n", > - prefix, var->name, rc); > - rc = 0; > + CERROR("%s: error writing proc entry '%.*s': rc = %d\n", > + prefix, keylen, key, rc); It's not a "proc" entry anymore :) Other than that minor issue, and the question about namelen, this looks semi-sane to me. Want to resend this as a non-rfc patch? thanks, greg k-h From gregkh at linuxfoundation.org Sun Mar 19 04:47:32 2017 From: gregkh at linuxfoundation.org (Greg Kroah-Hartman) Date: Sun, 19 Mar 2017 12:47:32 +0800 Subject: [lustre-devel] [PATCH/RFC] staging/lustre: Rework class_process_proc_param In-Reply-To: References: <20170318062408.3207381-1-green@linuxhacker.ru> <20170318103443.GA21943@kroah.com> <9C67F0F2-005F-4D70-8320-9255625CB543@linuxhacker.ru> <20170319042939.GA32423@kroah.com> Message-ID: <20170319044732.GA1455@kroah.com> On Sun, Mar 19, 2017 at 12:41:20AM -0400, Oleg Drokin wrote: > > On Mar 19, 2017, at 12:29 AM, Greg Kroah-Hartman wrote: > > > On Sat, Mar 18, 2017 at 11:17:55AM -0400, Oleg Drokin wrote: > >> > >> On Mar 18, 2017, at 6:34 AM, Greg Kroah-Hartman wrote: > >> > >>> On Sat, Mar 18, 2017 at 02:24:08AM -0400, Oleg Drokin wrote: > >>>> Ever since sysfs migration, class_process_proc_param stopped working > >>>> correctly as all the useful params were no longer present as lvars. > >>>> Replace all the nasty fake proc writes with hopefully less nasty > >>>> kobject attribute search and then update the attributes as needed. > >>>> > >>>> Signed-off-by: Oleg Drokin > >>>> Reported-by: Al Viro > >>>> --- > >>>> Al has quite rightfully complained in the past that class_process_proc_param > >>>> is a terrible piece of code and needs to go. > >>>> This patch is an attempt at improving it somewhat and in process drop > >>>> all the user/kernel address space games we needed to play to make it work > >>>> in the past (and which I suspect attracted Al's attention in the first place). > >>>> > >>>> Now I wonder if iterating kobject attributes like that would be ok with > >>>> you Greg, or do you think there is a better way? > >>>> class_find_write_attr could be turned into something generic since it's > >>>> certainly convenient to reuse same table of name-write_method pairs, > >>>> but I did some cursory research and nobody else seems to need anything > >>>> of the sort in-tree. > >>>> > >>>> I know ll_process_config is still awful and I will likely just > >>>> replace the current hack with kset_find_obj, but I just wanted to make > >>>> sure this new approach would be ok before spending too much time on it. > >>> > >>> I'm not quite sure what exactly you are even trying to do here. What is > >>> this interface? Who calls it, and how? What does it want to do? > >> > >> This is a configuration client code. > >> Management server has ability to pass down config information in the form of: > >> fsname.subsystem.attribute=value to clients and other servers > >> (subsystem determines if it's something of interest of clients or servers or > >> both). > >> This could be changed in the real time - i.e. you update it on the server and > >> that gets propagated to all the clients/servers, so no need to ssh into > >> every node to manually apply those changes and worry about client restarts > >> (the config is remembered at the management server and would be applied to any > >> new nodes connecting/across server restarts and such). > >> > >> So the way it then works then is once the string fsname.subsystem.attribute=value is delivered to the client, we find all instances of filesystem with fsname and then > >> all subsystems within it (one kobject per subsystem instance) and then update the > >> attributes to the value supplied. > >> > >> The same filesystem might be mounted more than once and then some layers might have > >> multiple instances inside a single filesystems. > >> > >> In the end it would turn something like lustre.osc.max_dirty_mb=128 into > >> writes to > >> /sys/fs/lustre/osc/lustre-OST0000-osc-ffff8800d75ca000/max_dirty_mb and > >> /sys/fs/lustre/osc/lustre-OST0001-osc-ffff8800d75ca000/max_dirty_mb > >> without actually iterating in sysfs namespace. > > > > Wait, who is doing the "write"? From within the kernel? Or some > > userspace app? I'm guessing from within the kernel, you are receiving > > the data from some other transport within the filesystem and then need > > to apply the settings? > > Yes, kernel code gets the notification "hey, there's a config change, come get it", > then it requests the diff in the config and does the "write' by updating the > attributes. > > >> The alternative we considered is we can probably just do an upcall and have > >> a userspace tool called with the parameter verbatim and try to figure it out, > >> but that seems a lot less ideal, and also we'll get a bunch of complications from > >> containers and such too, I imagine. > > > > Yeah, no, don't do an upcall, that's a mess. > > > >> The function pre-this patch is assuming that all these values are part of > >> a list of procfs values (no longer true after sysfs migration) so just iterates > >> that list and calls the write for matched names (but also needs to supply a userspace > >> buffer so looks much uglier too). > > > > For kobjects, you don't need userspace buffers, so this should be > > easier. > > Right, it's less of a mess due to that. > > >> Hopefully this makes at least some sense. > > > > Yes, a bit more, but ugh, what a mess :) > > Overall big systems are quite messy in many ways no matter what you do, > so it's always a case of pick your poison. Oh I know, I wasn't complaining, it's just a fact of life :) > >>> You can look up attributes for a kobject easily in the show/store > >>> functions (and some drivers just have a generic one and then you look at > >>> the string to see which attribute you are wanting to reference.) But > >>> you seem to be working backwards here, why do you have to look up a > >>> kobject? > >> > >> But that leads to the need to list attribute names essentially twice: > >> once for the attributes list, once in the show/set function to figure > >> out how to deal with that name. > > > > Yes, you don't need/want to do that. > > > > Let me go review the code now with that info, thanks, it makes more > > sense. > > Thanks! > In the end if the approach is mostly acceptable, I imagine if we just register the > kobject for the config changes, we can do away with the individual layers calling the > class_process_attr_param and instead have the class_process_config() call it directly > more or less. Yes, that seems like it would work as well. thanks, greg k-h From green at linuxhacker.ru Sun Mar 19 04:50:04 2017 From: green at linuxhacker.ru (Oleg Drokin) Date: Sun, 19 Mar 2017 00:50:04 -0400 Subject: [lustre-devel] [PATCH/RFC] staging/lustre: Rework class_process_proc_param In-Reply-To: <20170319044147.GA931@kroah.com> References: <20170318062408.3207381-1-green@linuxhacker.ru> <20170319044147.GA931@kroah.com> Message-ID: On Mar 19, 2017, at 12:41 AM, Greg Kroah-Hartman wrote: > On Sat, Mar 18, 2017 at 02:24:08AM -0400, Oleg Drokin wrote: >> Ever since sysfs migration, class_process_proc_param stopped working >> correctly as all the useful params were no longer present as lvars. >> Replace all the nasty fake proc writes with hopefully less nasty >> kobject attribute search and then update the attributes as needed. >> >> Signed-off-by: Oleg Drokin >> Reported-by: Al Viro >> --- >> Al has quite rightfully complained in the past that class_process_proc_param >> is a terrible piece of code and needs to go. >> This patch is an attempt at improving it somewhat and in process drop >> all the user/kernel address space games we needed to play to make it work >> in the past (and which I suspect attracted Al's attention in the first place). >> >> Now I wonder if iterating kobject attributes like that would be ok with >> you Greg, or do you think there is a better way? >> class_find_write_attr could be turned into something generic since it's >> certainly convenient to reuse same table of name-write_method pairs, >> but I did some cursory research and nobody else seems to need anything >> of the sort in-tree. >> >> I know ll_process_config is still awful and I will likely just >> replace the current hack with kset_find_obj, but I just wanted to make >> sure this new approach would be ok before spending too much time on it. >> >> Thanks! >> >> drivers/staging/lustre/lustre/include/obd_class.h | 4 +- >> drivers/staging/lustre/lustre/llite/llite_lib.c | 10 +-- >> drivers/staging/lustre/lustre/lov/lov_obd.c | 3 +- >> drivers/staging/lustre/lustre/mdc/mdc_request.c | 3 +- >> .../staging/lustre/lustre/obdclass/obd_config.c | 78 ++++++++++------------ >> drivers/staging/lustre/lustre/osc/osc_request.c | 3 +- >> 6 files changed, 44 insertions(+), 57 deletions(-) >> >> diff --git a/drivers/staging/lustre/lustre/include/obd_class.h b/drivers/staging/lustre/lustre/include/obd_class.h >> index 083a6ff..badafb8 100644 >> --- a/drivers/staging/lustre/lustre/include/obd_class.h >> +++ b/drivers/staging/lustre/lustre/include/obd_class.h >> @@ -114,8 +114,8 @@ typedef int (*llog_cb_t)(const struct lu_env *, struct llog_handle *, >> struct llog_rec_hdr *, void *); >> /* obd_config.c */ >> int class_process_config(struct lustre_cfg *lcfg); >> -int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars, >> - struct lustre_cfg *lcfg, void *data); >> +int class_process_attr_param(char *prefix, struct kobject *kobj, >> + struct lustre_cfg *lcfg); > > As you are exporting these functions, they will need to end up with a > lustre_* prefix eventually :) ok. > >> struct obd_device *class_incref(struct obd_device *obd, >> const char *scope, const void *source); >> void class_decref(struct obd_device *obd, >> diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c >> index 7b80040..192b877 100644 >> --- a/drivers/staging/lustre/lustre/llite/llite_lib.c >> +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c >> @@ -2259,7 +2259,7 @@ int ll_obd_statfs(struct inode *inode, void __user *arg) >> int ll_process_config(struct lustre_cfg *lcfg) >> { >> char *ptr; >> - void *sb; >> + struct super_block *sb; >> struct lprocfs_static_vars lvars; >> unsigned long x; >> int rc = 0; >> @@ -2273,15 +2273,15 @@ int ll_process_config(struct lustre_cfg *lcfg) >> rc = kstrtoul(ptr, 16, &x); >> if (rc != 0) >> return -EINVAL; >> - sb = (void *)x; >> + sb = (struct super_block *)x; >> /* This better be a real Lustre superblock! */ >> - LASSERT(s2lsi((struct super_block *)sb)->lsi_lmd->lmd_magic == LMD_MAGIC); >> + LASSERT(s2lsi(sb)->lsi_lmd->lmd_magic == LMD_MAGIC); >> >> /* Note we have not called client_common_fill_super yet, so >> * proc fns must be able to handle that! >> */ >> - rc = class_process_proc_param(PARAM_LLITE, lvars.obd_vars, >> - lcfg, sb); >> + rc = class_process_attr_param(PARAM_LLITE, &ll_s2sbi(sb)->ll_kobj, >> + lcfg); >> if (rc > 0) >> rc = 0; >> return rc; >> diff --git a/drivers/staging/lustre/lustre/lov/lov_obd.c b/drivers/staging/lustre/lustre/lov/lov_obd.c >> index b3161fb..c33a327 100644 >> --- a/drivers/staging/lustre/lustre/lov/lov_obd.c >> +++ b/drivers/staging/lustre/lustre/lov/lov_obd.c >> @@ -926,8 +926,7 @@ int lov_process_config_base(struct obd_device *obd, struct lustre_cfg *lcfg, >> >> lprocfs_lov_init_vars(&lvars); >> >> - rc = class_process_proc_param(PARAM_LOV, lvars.obd_vars, >> - lcfg, obd); >> + rc = class_process_attr_param(PARAM_LOV, &obd->obd_kobj, lcfg); >> if (rc > 0) >> rc = 0; >> goto out; >> diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c >> index 6bc2fb8..00387b8 100644 >> --- a/drivers/staging/lustre/lustre/mdc/mdc_request.c >> +++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c >> @@ -2670,8 +2670,7 @@ static int mdc_process_config(struct obd_device *obd, u32 len, void *buf) >> lprocfs_mdc_init_vars(&lvars); >> switch (lcfg->lcfg_command) { >> default: >> - rc = class_process_proc_param(PARAM_MDC, lvars.obd_vars, >> - lcfg, obd); >> + rc = class_process_attr_param(PARAM_MDC, &obd->obd_kobj, lcfg); >> if (rc > 0) >> rc = 0; >> break; >> diff --git a/drivers/staging/lustre/lustre/obdclass/obd_config.c b/drivers/staging/lustre/lustre/obdclass/obd_config.c >> index 8fce88f..08fd126 100644 >> --- a/drivers/staging/lustre/lustre/obdclass/obd_config.c >> +++ b/drivers/staging/lustre/lustre/obdclass/obd_config.c >> @@ -995,26 +995,42 @@ int class_process_config(struct lustre_cfg *lcfg) >> } >> EXPORT_SYMBOL(class_process_config); >> >> -int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars, >> - struct lustre_cfg *lcfg, void *data) >> +static int class_find_write_attr(struct kobject *kobj, char *name, int namelen, >> + char *val, int vallen) >> +{ >> + struct attribute *attr; >> + struct kobj_type *kt = get_ktype(kobj); >> + int i; >> + >> + /* Empty object? */ >> + if (!kt || !kt->default_attrs) >> + return -ENOENT; >> + >> + for (i = 0; (attr = kt->default_attrs[i]) != NULL; i++) { >> + if (!strncmp(attr->name, name, namelen) && >> + namelen == strlen(attr->name)) { > > Why do you care about namelen? Why can't you just do a "normal" > strcmp()? Is this "untrusted" user data? in this patch, name is not NULL terminated (see the caller, need to doublecheck it's safe to replace = with \0, which it might not be if the same buffer is reused by others.) >> + if (kt->sysfs_ops && kt->sysfs_ops->store) >> + return kt->sysfs_ops->store(kobj, attr, val, >> + vallen); >> + return -EINVAL; >> + } >> + } >> + >> + return -ENOENT; >> +} >> + >> +int class_process_attr_param(char *prefix, struct kobject *kobj, >> + struct lustre_cfg *lcfg) >> { >> - struct lprocfs_vars *var; >> - struct file fakefile; >> - struct seq_file fake_seqfile; >> char *key, *sval; >> int i, keylen, vallen; >> - int matched = 0, j = 0; >> int rc = 0; >> - int skip = 0; >> >> if (lcfg->lcfg_command != LCFG_PARAM) { >> CERROR("Unknown command: %d\n", lcfg->lcfg_command); >> return -EINVAL; >> } >> >> - /* fake a seq file so that var->fops->write can work... */ >> - fakefile.private_data = &fake_seqfile; >> - fake_seqfile.private = data; >> /* e.g. tunefs.lustre --param mdt.group_upcall=foo /r/tmp/lustre-mdt >> * or lctl conf_param lustre-MDT0000.mdt.group_upcall=bar >> * or lctl conf_param lustre-OST0000.osc.max_dirty_mb=36 >> @@ -1038,39 +1054,16 @@ int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars, >> keylen = sval - key; >> sval++; >> vallen = strlen(sval); >> - matched = 0; >> - j = 0; >> - /* Search proc entries */ >> - while (lvars[j].name) { >> - var = &lvars[j]; >> - if (!class_match_param(key, var->name, NULL) && >> - keylen == strlen(var->name)) { >> - matched++; >> - rc = -EROFS; >> - if (var->fops && var->fops->write) { >> - mm_segment_t oldfs; >> - >> - oldfs = get_fs(); >> - set_fs(KERNEL_DS); >> - rc = var->fops->write(&fakefile, >> - (const char __user *)sval, >> - vallen, NULL); >> - set_fs(oldfs); >> - } >> - break; >> - } >> - j++; >> - } >> - if (!matched) { >> + rc = class_find_write_attr(kobj, key, keylen, sval, vallen); >> + >> + if (rc == -ENOENT) { >> CERROR("%.*s: %s unknown param %s\n", >> (int)strlen(prefix) - 1, prefix, >> (char *)lustre_cfg_string(lcfg, 0), key); >> /* rc = -EINVAL; continue parsing other params */ >> - skip++; >> } else if (rc < 0) { >> - CERROR("%s: error writing proc entry '%s': rc = %d\n", >> - prefix, var->name, rc); >> - rc = 0; >> + CERROR("%s: error writing proc entry '%.*s': rc = %d\n", >> + prefix, keylen, key, rc); > > It's not a "proc" entry anymore :) Indeed. > Other than that minor issue, and the question about namelen, this looks > semi-sane to me. Want to resend this as a non-rfc patch? I'd do a bit deeper change then (or a set, I guess) to fix up some other wrinkles, so probably not right away. Thanks again! From yanli at ascar.io Tue Mar 21 19:43:27 2017 From: yanli at ascar.io (Yan Li) Date: Tue, 21 Mar 2017 12:43:27 -0700 Subject: [lustre-devel] [PATCH 0/6] Rate-limiting Quality of Service Message-ID: This patch enables rate-limiting quality of service (RLQOS) support as talked in the ASCAR paper [1]. The purpose of RLQOS is to provide a client-side rate limiting mechanism that controls max_rpcs_in_flight and minimal gap between brw RPC requests (called tau in the code and paper). It is very different from the existing LOV QOS in Lustre. I have presented this work at LUG'16 and am sorry for the belated code release. This is my first code patch to the Lustre mailing list so I'm sure lot of things can be improved. Please kindly let me know. The main idea is to provide a rule-based rate limiting mechanism on Lustre clients that can be used to ease congestion and improve performance during peak hours. The rules designate how max_rpcs_in_flight and tau can be changed based on three metrics. The rules are set through a procfs handle. In the research paper [1], a machine learning-based heuristics method is used to generate the traffic control rules that can improve performance. The traffic control rules can also be hand crafted based on benchmark results. I probably should write more details here but the email would be rather long. The paper [1] has detailed introduction of the idea and implementation. I also believe there should be better documentation on this feature. I'm not sure if I should create a wiki page for this or provide a documentation within the code base. This function is still under development, and the latest code can be found at https://github.com/mlogic/ascar-lustre-2.9-client . This research was supported in part by the National Science Foundation under awards IIP-1266400, CCF-1219163, CNS-1018928, CNS-1528179, by the Department of Energy under award DE-FC02-10ER26017/DESC0005417, by a Symantec Graduate Fellowship, by a grant from Intel Corporation, and by industrial members of the Center for Research in Storage Systems in UC Santa Cruz. [1] http://storageconference.us/2015/Papers/14.Li.pdf Yan Li (6): Autoconf option for rate-limiting Quality of Service (RLQOS) Added fields to message for RLQOS support RLQOS main data structure lprocfs interfaces for showing, parsing, and controlling rules Throttle the outgoing requests according to tau Adjust max_rpcs_in_flight according to metrics lustre/autoconf/lustre-core.m4 | 17 ++++ lustre/include/Makefile.am | 3 +- lustre/include/lustre/lustre_idl.h | 4 + lustre/include/obd.h | 8 ++ lustre/include/rlqos.h | 136 ++++++++++++++++++++++++++++++ lustre/obdclass/genops.c | 25 ++++++ lustre/obdclass/lprocfs_status.c | 32 +++++++ lustre/osc/Makefile.in | 2 +- lustre/osc/lproc_osc.c | 157 ++++++++++++++++++++++++++++++----- lustre/osc/osc_cache.c | 3 + lustre/osc/osc_internal.h | 66 +++++++++++++++ lustre/osc/osc_request.c | 165 +++++++++++++++++++++++++++++++++++++ lustre/osc/qos_rules.c | 125 ++++++++++++++++++++++++++++ lustre/ptlrpc/pack_generic.c | 5 ++ lustre/ptlrpc/wiretest.c | 2 + lustre/utils/wiretest.c | 2 + 16 files changed, 730 insertions(+), 22 deletions(-) create mode 100644 lustre/include/rlqos.h create mode 100644 lustre/osc/qos_rules.c -- 1.8.3.1 From yanli at ascar.io Tue Mar 21 19:43:31 2017 From: yanli at ascar.io (Yan Li) Date: Tue, 21 Mar 2017 12:43:31 -0700 Subject: [lustre-devel] [PATCH 4/6] lprocfs interfaces for showing, parsing, and controlling rules In-Reply-To: References: Message-ID: Signed-off-by: Yan Li --- lustre/obdclass/lprocfs_status.c | 32 ++++++++ lustre/osc/Makefile.in | 2 +- lustre/osc/lproc_osc.c | 157 ++++++++++++++++++++++++++++++++++----- lustre/osc/qos_rules.c | 125 +++++++++++++++++++++++++++++++ 4 files changed, 295 insertions(+), 21 deletions(-) create mode 100644 lustre/osc/qos_rules.c diff --git a/lustre/obdclass/lprocfs_status.c b/lustre/obdclass/lprocfs_status.c index 08db676..841a3da 100644 --- a/lustre/obdclass/lprocfs_status.c +++ b/lustre/obdclass/lprocfs_status.c @@ -814,6 +814,14 @@ int lprocfs_import_seq_show(struct seq_file *m, void *data) int j; int k; int rw = 0; +#ifdef ENABLE_RLQOS + struct qos_data_t *qos; + __u64 ack_ewma; + __u64 sent_ewma; + int rtt_ratio100; + __u64 read_tp; + __u64 write_tp; +#endif LASSERT(obd != NULL); LPROCFS_CLIMP_CHECK(obd); @@ -884,6 +892,26 @@ int lprocfs_import_seq_show(struct seq_file *m, void *data) atomic_read(&imp->imp_unregistering), atomic_read(&imp->imp_timeouts), ret.lc_sum, header->lc_units); +#ifdef ENABLE_RLQOS + qos = &obd->u.cli.qos; + spin_lock(&qos->lock); + ack_ewma = qos_get_ewma_usec(&qos->ack_ewma); + sent_ewma = qos_get_ewma_usec(&qos->sent_ewma); + rtt_ratio100 = qos->rtt_ratio100; + + /* Refresh throughput. If a long time has passed since we + received last req, throughput data is stale. */ + calc_throughput(qos, OST_READ-OST_READ, 0); + calc_throughput(qos, OST_WRITE-OST_READ, 0); + + read_tp = qos->tp_last_sec[0]; + write_tp = qos->tp_last_sec[1]; + spin_unlock(&qos->lock); + seq_printf(m, " ack_ewma: %llu usec\n" + " sent_ewma: %llu usec\n" + " rtt_ratio100: %d\n", + ack_ewma, sent_ewma, rtt_ratio100); +#endif k = 0; for(j = 0; j < IMP_AT_MAX_PORTALS; j++) { @@ -938,6 +966,10 @@ int lprocfs_import_seq_show(struct seq_file *m, void *data) k / j, (100 * k / j) % 100); } } +#ifdef ENABLE_RLQOS + seq_printf(m, " read_throughput: %llu\n", read_tp); + seq_printf(m, " write_throughput: %llu\n", write_tp); +#endif out_climp: LPROCFS_CLIMP_EXIT(obd); diff --git a/lustre/osc/Makefile.in b/lustre/osc/Makefile.in index b1128bc..d6edab2 100644 --- a/lustre/osc/Makefile.in +++ b/lustre/osc/Makefile.in @@ -1,5 +1,5 @@ MODULES := osc -osc-objs := osc_request.o lproc_osc.o osc_dev.o osc_object.o osc_page.o osc_lock.o osc_io.o osc_quota.o osc_cache.o +osc-objs := osc_request.o lproc_osc.o osc_dev.o osc_object.o osc_page.o osc_lock.o osc_io.o osc_quota.o osc_cache.o qos_rules.o EXTRA_DIST = $(osc-objs:%.o=%.c) osc_internal.h osc_cl_internal.h diff --git a/lustre/osc/lproc_osc.c b/lustre/osc/lproc_osc.c index de5a29c..653afc4 100644 --- a/lustre/osc/lproc_osc.c +++ b/lustre/osc/lproc_osc.c @@ -1,3 +1,4 @@ + /* * GPL HEADER START * @@ -38,6 +39,9 @@ #include #include #include "osc_internal.h" +#ifdef ENABLE_RLQOS +# include "../include/rlqos.h" +#endif #ifdef CONFIG_PROC_FS static int osc_active_seq_show(struct seq_file *m, void *v) @@ -92,8 +96,10 @@ static ssize_t osc_max_rpcs_in_flight_seq_write(struct file *file, { struct obd_device *dev = ((struct seq_file *)file->private_data)->private; struct client_obd *cli = &dev->u.cli; +#ifdef ENABLE_RLQOS + struct qos_data_t *qos = &cli->qos; +#endif int rc; - int adding, added, req_count; __s64 val; rc = lprocfs_str_to_s64(buffer, count, &val); @@ -103,31 +109,57 @@ static ssize_t osc_max_rpcs_in_flight_seq_write(struct file *file, return -ERANGE; LPROCFS_CLIMP_CHECK(dev); + set_max_rpcs_in_flight((int)val, cli); + LPROCFS_CLIMP_EXIT(dev); - adding = (int)val - cli->cl_max_rpcs_in_flight; - req_count = atomic_read(&osc_pool_req_count); - if (adding > 0 && req_count < osc_reqpool_maxreqcount) { - /* - * There might be some race which will cause over-limit - * allocation, but it is fine. - */ - if (req_count + adding > osc_reqpool_maxreqcount) - adding = osc_reqpool_maxreqcount - req_count; - - added = osc_rq_pool->prp_populate(osc_rq_pool, adding); - atomic_add(added, &osc_pool_req_count); - } - - spin_lock(&cli->cl_loi_list_lock); - cli->cl_max_rpcs_in_flight = val; - client_adjust_max_dirty(cli); - spin_unlock(&cli->cl_loi_list_lock); +#ifdef ENABLE_RLQOS + /* Update the value tracked by QoS routines too */ + spin_lock(&qos->lock); + qos->max_rpc_in_flight100 = val * 100; + spin_unlock(&qos->lock); +#endif - LPROCFS_CLIMP_EXIT(dev); return count; } LPROC_SEQ_FOPS(osc_max_rpcs_in_flight); +#ifdef ENABLE_RLQOS +static int osc_min_brw_rpc_gap_seq_show(struct seq_file *m, void *v) +{ + struct obd_device *dev = m->private; + struct client_obd *cli = &dev->u.cli; + struct qos_data_t *qos = &cli->qos; + + spin_lock(&qos->lock); + seq_printf(m, "%u\n", qos->min_usec_between_rpcs); + spin_unlock(&qos->lock); + return 0; +} + +static ssize_t osc_min_brw_rpc_gap_seq_write(struct file *file, + const char __user *buffer, + size_t count, loff_t *off) +{ + struct obd_device *dev = ((struct seq_file *)file->private_data)->private; + struct client_obd *cli = &dev->u.cli; + int rc; + __s64 val; + struct qos_data_t *qos = &cli->qos; + + rc = lprocfs_str_to_s64(buffer, count, &val); + if (rc) + return rc; + if (val < 0) + return -ERANGE; + + spin_lock(&qos->lock); + qos->min_usec_between_rpcs = val; + spin_unlock(&qos->lock); + return count; +} +LPROC_SEQ_FOPS(osc_min_brw_rpc_gap); +#endif + static int osc_max_dirty_mb_seq_show(struct seq_file *m, void *v) { struct obd_device *dev = m->private; @@ -599,6 +631,83 @@ static int osc_unstable_stats_seq_show(struct seq_file *m, void *v) } LPROC_SEQ_FOPS_RO(osc_unstable_stats); +#ifdef ENABLE_RLQOS +static int osc_qos_rules_seq_show(struct seq_file *m, void *data) +{ + struct obd_device *dev = m->private; + struct client_obd *cli = &dev->u.cli; + struct qos_data_t *qos = &cli->qos; + int i; + struct qos_rule_t *r; + + spin_lock(&qos->lock); + if (0 == qos->rule_no || NULL == qos->rules || 0 == qos->min_gap_between_updating_mrif) { + seq_printf(m, "0\n"); + /* Make sure the upcoming for loop doesn't run */ + qos->rule_no = 0; + } else { + seq_printf(m, "%d,%d\n", qos->rule_no, 1000000 / qos->min_gap_between_updating_mrif); + } + for (i = 0; i < qos->rule_no; ++i) { + r = &qos->rules[i]; + seq_printf(m, "%llu,%llu,%llu,%llu,%u,%u,%d,%d,%u,%d,%llu,%llu,%u\n", + r->ack_ewma_lower, r->ack_ewma_upper, + r->send_ewma_lower, r->send_ewma_upper, + r->rtt_ratio100_lower, r->rtt_ratio100_upper, + r->m100, r->b100, r->tau, + r->used_times, + r->ack_ewma_avg, r->send_ewma_avg, r->rtt_ratio100_avg); + } + spin_unlock(&qos->lock); + return 0; +} + +static ssize_t osc_qos_rules_seq_write(struct file *file, + const char __user *buffer, + size_t count, loff_t *off) +{ + struct obd_device *dev = ((struct seq_file *)file->private_data)->private; + struct client_obd *cli = &dev->u.cli; + struct qos_data_t *qos = &cli->qos; + int rc; + char *kernbuf = NULL; + + OBD_ALLOC(kernbuf, count + 1); + if (NULL == kernbuf) { + return -ENOMEM; + } + if (copy_from_user(kernbuf, buffer, count)) { + rc = -EFAULT; + goto out_free_kernbuf; + } + /* Make sure the buf ends with a null so that sscanf won't overread */ + kernbuf[count] = '\0'; + + spin_lock(&qos->lock); + /* parse_qos_rules() will free existing rules in qos before starting parsing */ + rc = parse_qos_rules(kernbuf, qos); + if (0 == rc) { + /* return the number of chars processed on a success parsing */ + rc = count; + } + qos->ack_ewma.ea = 0; + qos->ack_ewma.last_time.tv_sec = 0; + qos->ack_ewma.last_time.tv_usec = 0; + qos->sent_ewma.ea = 0; + qos->sent_ewma.last_time.tv_sec = 0; + qos->sent_ewma.last_time.tv_usec = 0; + qos->rtt_ratio100 = 0; + qos->smallest_rtt = 0; + qos->min_usec_between_rpcs = 0; + spin_unlock(&qos->lock); +out_free_kernbuf: + OBD_FREE(kernbuf, count + 1); + return rc; + +} +LPROC_SEQ_FOPS(osc_qos_rules); +#endif + LPROC_SEQ_FOPS_RO_TYPE(osc, uuid); LPROC_SEQ_FOPS_RO_TYPE(osc, connect_flags); LPROC_SEQ_FOPS_RO_TYPE(osc, blksize); @@ -647,6 +756,10 @@ struct lprocfs_vars lprocfs_osc_obd_vars[] = { .fops = &osc_obd_max_pages_per_rpc_fops }, { .name = "max_rpcs_in_flight", .fops = &osc_max_rpcs_in_flight_fops }, +#ifdef ENABLE_RLQOS + { .name = "min_brw_rpc_gap", + .fops = &osc_min_brw_rpc_gap_fops }, +#endif { .name = "destroys_in_flight", .fops = &osc_destroys_in_flight_fops }, { .name = "max_dirty_mb", @@ -683,6 +796,10 @@ struct lprocfs_vars lprocfs_osc_obd_vars[] = { .fops = &osc_pinger_recov_fops }, { .name = "unstable_stats", .fops = &osc_unstable_stats_fops }, +#ifdef ENABLE_RLQOS + { .name = "qos_rules", + .fops = &osc_qos_rules_fops }, +#endif { NULL } }; diff --git a/lustre/osc/qos_rules.c b/lustre/osc/qos_rules.c new file mode 100644 index 0000000..8db24bd --- /dev/null +++ b/lustre/osc/qos_rules.c @@ -0,0 +1,125 @@ +/* + * GPL HEADER START + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 only, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License version 2 for more details (a copy is included + * in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; If not, see + * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf + * + * Please contact Storage Systems Research Center, Computer Science Department, + * University of California, Santa Cruz (www.ssrc.ucsc.edu) if you need + * additional information or have any questions. + * + * GPL HEADER END + */ +/* + * Copyright (c) 2013-2017, University of California, Santa Cruz, CA, USA. + * All rights reserved. + */ +/* + * This file is part of Lustre, http://www.lustre.org/ + * Lustre is a trademark of Sun Microsystems, Inc. + * + * qos_rules.c + */ +#ifndef __KERNEL__ + #include + #include "kernel-test-primitives.h" + #include +#endif +#include "../include/rlqos.h" + +/* Parse qos_rules in buf and store the result to qos. + * + * Pre-condition: + * 1. qos must be initialized and qos->lock MUST be held before calling this function! + * 2. exisiting rules in qos->rules will be freed + * 3. buf must be NULL-terminated or sscanf may overread it. + * + * Return value: + * 0: success + * other value: error code. On error, qos->rules is NULL and qos->rule_no is 0. + */ +int parse_qos_rules(const char *buf, struct qos_data_t *qos) +{ + int new_rule_no = 0; + int rules_per_sec = 0; + int rc; + int i; + const char *p = buf; + int n; + const size_t rule_size = sizeof(*(qos->rules)); + struct qos_rule_t *r; + + /* handle "0\n" and "0" */ + if (strlen(p) <= 2 && '0' == *p) { + if (qos->rules) { + LIBCFS_FREE(qos->rules, qos->rule_no * rule_size); + } + qos->rule_no = 0; + qos->rules = NULL; + return 0; + } + + rc = sscanf(p, "%d,%d\n%n", &new_rule_no, &rules_per_sec, &n); + if (2 != rc) { + CWARN("Input data error, can't read new_rule_no\n"); + return -EINVAL; + } + if (0 == new_rule_no || 0 == rules_per_sec) { + if (qos->rules) { + LIBCFS_FREE(qos->rules, qos->rule_no * rule_size); + } + qos->rule_no = 0; + qos->rules = NULL; + return 0; + } + p += n; + if (qos->rules) { + LIBCFS_FREE(qos->rules, qos->rule_no * rule_size); + } + qos->rule_no = new_rule_no; + qos->min_gap_between_updating_mrif = 1000000 / rules_per_sec; + LIBCFS_ALLOC_ATOMIC(qos->rules, new_rule_no * rule_size); + if (!qos->rules) { + CWARN("Can't allocate enough mem for %d rules\n", new_rule_no); + return -ENOMEM; + } + memset(qos->rules, 0, new_rule_no * rule_size); + + for (i = 0; i < new_rule_no; i++) { + r = &qos->rules[i]; + /* Don't put \n at the end of sscanf format str + because there may be other unknown fields there, + which will be discarded later */ + rc = sscanf(p, "%llu,%llu,%llu,%llu,%u,%u,%d,%d,%u%n", + &r->ack_ewma_lower, &r->ack_ewma_upper, + &r->send_ewma_lower, &r->send_ewma_upper, + &r->rtt_ratio100_lower, &r->rtt_ratio100_upper, + &r->m100, &r->b100, &r->tau, &n); + p += n; + if (rc != 9) { + CWARN("QoS rule parsing error, rc = %d\n", rc); + LIBCFS_FREE(qos->rules, qos->rule_no * rule_size); + qos->rules = NULL; + qos->rule_no = 0; + return -EINVAL; + } + /* consume all other chars till \n or end-of-buffer */ + while (*p != '\0' && *(p++) != '\n') + ; + } + + return 0; +} -- 1.8.3.1 From yanli at ascar.io Tue Mar 21 19:43:28 2017 From: yanli at ascar.io (Yan Li) Date: Tue, 21 Mar 2017 12:43:28 -0700 Subject: [lustre-devel] [PATCH 1/6] Autoconf option for rate-limiting Quality of Service (RLQOS) In-Reply-To: References: Message-ID: <99fe8fdaaaa5b6fd36c0782269bc45a580079696.1490122510.git.yanli@ascar.io> This patch enables rate-limiting quality of service (RLQOS) support as talked in the ASCAR paper [1]. The purpose of RLQOS is to provide a client-side rate limiting mechanism that controls max_rpcs_in_flight and minimal gap between brw RPC requests (called tau in the code and paper). RLQOS can be enabled by passing --enable-rlqos to configure. It then can be controlled by tunables in procfs of each osc. [1] http://storageconference.us/2015/Papers/14.Li.pdf Signed-off-by: Yan Li --- lustre/autoconf/lustre-core.m4 | 17 +++++++++++++++++ lustre/include/Makefile.am | 3 ++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/lustre/autoconf/lustre-core.m4 b/lustre/autoconf/lustre-core.m4 index 0578325..7f1828e 100644 --- a/lustre/autoconf/lustre-core.m4 +++ b/lustre/autoconf/lustre-core.m4 @@ -369,6 +369,22 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([ AC_MSG_RESULT([$enable_ssk]) ]) # LC_OPENSSL_SSK +# +# LC_CONFIG_RLQOS +# +# Rate-limiting Quality of Service support +# +AC_DEFUN([LC_CONFIG_RLQOS], [ +AC_MSG_CHECKING([whether to enable rate-limiting quality of service support]) +AC_ARG_ENABLE([rlqos], + AC_HELP_STRING([--enable-rlqos], + [enable rate-limiting quality of service support]), + [], [enable_rlqos="no"]) +AC_MSG_RESULT([$enable_rlqos]) +AS_IF([test "x$enable_rlqos" != xno], + [AC_DEFINE(ENABLE_RLQOS, 1, [enable rate-limiting quality of service support])]) +]) # LC_CONFIG_RLQOS + # LC_INODE_PERMISION_2ARGS # # up to v2.6.27 had a 3 arg version (inode, mask, nameidata) @@ -2241,6 +2257,7 @@ AC_DEFUN([LC_PROG_LINUX], [ LC_GLIBC_SUPPORT_FHANDLES LC_CONFIG_GSS LC_OPENSSL_SSK + LC_CONFIG_RLQOS # 2.6.32 LC_BLK_QUEUE_MAX_SEGMENTS diff --git a/lustre/include/Makefile.am b/lustre/include/Makefile.am index 9074ca4..6d72b6e 100644 --- a/lustre/include/Makefile.am +++ b/lustre/include/Makefile.am @@ -98,4 +98,5 @@ EXTRA_DIST = \ upcall_cache.h \ lustre_kernelcomm.h \ seq_range.h \ - uapi_kernelcomm.h + uapi_kernelcomm.h \ + rlqos.h -- 1.8.3.1 From yanli at ascar.io Tue Mar 21 19:43:29 2017 From: yanli at ascar.io (Yan Li) Date: Tue, 21 Mar 2017 12:43:29 -0700 Subject: [lustre-devel] [PATCH 2/6] Added fields to message for RLQOS support In-Reply-To: References: Message-ID: <28c79a11bf7df97be1d3355b83c55a4ceea177bc.1490122510.git.yanli@ascar.io> Modified the request message to embed sent_time, which will be returned from the server and used to calculate the exponentially weighted moving average of sent_time gap in return messages. It is used as a metric for rate-limiting quality of service. Signed-off-by: Yan Li --- lustre/include/lustre/lustre_idl.h | 4 ++++ lustre/ptlrpc/pack_generic.c | 5 +++++ lustre/ptlrpc/wiretest.c | 2 ++ lustre/utils/wiretest.c | 2 ++ 4 files changed, 13 insertions(+) diff --git a/lustre/include/lustre/lustre_idl.h b/lustre/include/lustre/lustre_idl.h index bf23a47..7a200d1 100644 --- a/lustre/include/lustre/lustre_idl.h +++ b/lustre/include/lustre/lustre_idl.h @@ -3336,8 +3336,12 @@ struct obdo { * each stripe. * brw: grant space consumed on * the client for the write */ +#ifdef ENABLE_RLQOS + struct timeval o_sent_time; /* timeval is 64x2 bits on Linux */ +#else __u64 o_padding_4; __u64 o_padding_5; +#endif __u64 o_padding_6; }; diff --git a/lustre/ptlrpc/pack_generic.c b/lustre/ptlrpc/pack_generic.c index 8df8ea8..d0bc87a 100644 --- a/lustre/ptlrpc/pack_generic.c +++ b/lustre/ptlrpc/pack_generic.c @@ -1722,8 +1722,13 @@ void lustre_swab_obdo (struct obdo *o) __swab32s (&o->o_uid_h); __swab32s (&o->o_gid_h); __swab64s (&o->o_data_version); +#ifdef ENABLE_RLQOS + __swab64s ((__u64*)&o->o_sent_time.tv_sec); + __swab64s ((__u64*)&o->o_sent_time.tv_usec); +#else CLASSERT(offsetof(typeof(*o), o_padding_4) != 0); CLASSERT(offsetof(typeof(*o), o_padding_5) != 0); +#endif CLASSERT(offsetof(typeof(*o), o_padding_6) != 0); } diff --git a/lustre/ptlrpc/wiretest.c b/lustre/ptlrpc/wiretest.c index 070ef91..0c909a6 100644 --- a/lustre/ptlrpc/wiretest.c +++ b/lustre/ptlrpc/wiretest.c @@ -1314,6 +1314,7 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct obdo, o_data_version)); LASSERTF((int)sizeof(((struct obdo *)0)->o_data_version) == 8, "found %lld\n", (long long)(int)sizeof(((struct obdo *)0)->o_data_version)); +#ifndef ENABLE_RLQOS LASSERTF((int)offsetof(struct obdo, o_padding_4) == 184, "found %lld\n", (long long)(int)offsetof(struct obdo, o_padding_4)); LASSERTF((int)sizeof(((struct obdo *)0)->o_padding_4) == 8, "found %lld\n", @@ -1322,6 +1323,7 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct obdo, o_padding_5)); LASSERTF((int)sizeof(((struct obdo *)0)->o_padding_5) == 8, "found %lld\n", (long long)(int)sizeof(((struct obdo *)0)->o_padding_5)); +#endif LASSERTF((int)offsetof(struct obdo, o_padding_6) == 200, "found %lld\n", (long long)(int)offsetof(struct obdo, o_padding_6)); LASSERTF((int)sizeof(((struct obdo *)0)->o_padding_6) == 8, "found %lld\n", diff --git a/lustre/utils/wiretest.c b/lustre/utils/wiretest.c index 233d7d8..47fbbf0 100644 --- a/lustre/utils/wiretest.c +++ b/lustre/utils/wiretest.c @@ -1329,6 +1329,7 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct obdo, o_data_version)); LASSERTF((int)sizeof(((struct obdo *)0)->o_data_version) == 8, "found %lld\n", (long long)(int)sizeof(((struct obdo *)0)->o_data_version)); +#ifndef ENABLE_RLQOS LASSERTF((int)offsetof(struct obdo, o_padding_4) == 184, "found %lld\n", (long long)(int)offsetof(struct obdo, o_padding_4)); LASSERTF((int)sizeof(((struct obdo *)0)->o_padding_4) == 8, "found %lld\n", @@ -1337,6 +1338,7 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct obdo, o_padding_5)); LASSERTF((int)sizeof(((struct obdo *)0)->o_padding_5) == 8, "found %lld\n", (long long)(int)sizeof(((struct obdo *)0)->o_padding_5)); +#endif LASSERTF((int)offsetof(struct obdo, o_padding_6) == 200, "found %lld\n", (long long)(int)offsetof(struct obdo, o_padding_6)); LASSERTF((int)sizeof(((struct obdo *)0)->o_padding_6) == 8, "found %lld\n", -- 1.8.3.1 From yanli at ascar.io Tue Mar 21 19:43:32 2017 From: yanli at ascar.io (Yan Li) Date: Tue, 21 Mar 2017 12:43:32 -0700 Subject: [lustre-devel] [PATCH 5/6] Throttle the outgoing requests according to tau In-Reply-To: References: Message-ID: <613cd7339035952e7f4dce3aa9f3db9e8bb52c92.1490122510.git.yanli@ascar.io> Signed-off-by: Yan Li --- lustre/osc/osc_cache.c | 3 +++ lustre/osc/osc_internal.h | 66 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/lustre/osc/osc_cache.c b/lustre/osc/osc_cache.c index 236263c..2f9d4e1 100644 --- a/lustre/osc/osc_cache.c +++ b/lustre/osc/osc_cache.c @@ -2316,6 +2316,9 @@ static int osc_io_unplug0(const struct lu_env *env, struct client_obd *cli, } else { CDEBUG(D_CACHE, "Queue writeback work for client %p.\n", cli); LASSERT(cli->cl_writeback_work != NULL); +#ifdef ENABLE_RLQOS + qos_throttle(&cli->qos); +#endif rc = ptlrpcd_queue_work(cli->cl_writeback_work); } return rc; diff --git a/lustre/osc/osc_internal.h b/lustre/osc/osc_internal.h index 06c21b3..d31d5ba 100644 --- a/lustre/osc/osc_internal.h +++ b/lustre/osc/osc_internal.h @@ -245,4 +245,70 @@ extern unsigned long osc_cache_shrink_count(struct shrinker *sk, extern unsigned long osc_cache_shrink_scan(struct shrinker *sk, struct shrink_control *sc); +#ifdef ENABLE_RLQOS +static inline void qos_throttle(struct qos_data_t *qos) +{ + struct timeval now; + long usec_since_last_rpc; + long need_sleep_usec = 0; + + spin_lock(&qos->lock); + if (0 == qos->min_usec_between_rpcs) + goto out; + + do_gettimeofday(&now); + usec_since_last_rpc = cfs_timeval_sub(&now, &qos->last_rpc_time, NULL); + if (usec_since_last_rpc < 0) { + usec_since_last_rpc = 0; + } + if (usec_since_last_rpc < qos->min_usec_between_rpcs) { + need_sleep_usec = qos->min_usec_between_rpcs - usec_since_last_rpc; + } + qos->last_rpc_time = now; +out: + spin_unlock(&qos->lock); + if (0 == need_sleep_usec) { + return; + } + + /* About timer ranges: + Ref: https://www.kernel.org/doc/Documentation/timers/timers-howto.txt */ + if (need_sleep_usec < 1000) { + udelay(need_sleep_usec); + } else if (need_sleep_usec < 20000) { + usleep_range(need_sleep_usec - 1, need_sleep_usec); + } else { + msleep(need_sleep_usec / 1000); + } +} +#endif /* ENABLE_RLQOS */ + +/* You must call LPROCFS_CLIMP_CHECK() on the obd device before and + * LPROCFS_CLIMP_EXIT() after calling this function. They are not called inside + * this function, because they may return an error code. + */ +static inline void set_max_rpcs_in_flight(int val, struct client_obd *cli) +{ + int adding, added, req_count; + + adding = val - cli->cl_max_rpcs_in_flight; + req_count = atomic_read(&osc_pool_req_count); + if (adding > 0 && req_count < osc_reqpool_maxreqcount) { + /* + * There might be some race which will cause over-limit + * allocation, but it is fine. + */ + if (req_count + adding > osc_reqpool_maxreqcount) + adding = osc_reqpool_maxreqcount - req_count; + + added = osc_rq_pool->prp_populate(osc_rq_pool, adding); + atomic_add(added, &osc_pool_req_count); + } + + spin_lock(&cli->cl_loi_list_lock); + cli->cl_max_rpcs_in_flight = val; + client_adjust_max_dirty(cli); + spin_unlock(&cli->cl_loi_list_lock); +} + #endif /* OSC_INTERNAL_H */ -- 1.8.3.1 From yanli at ascar.io Tue Mar 21 19:43:30 2017 From: yanli at ascar.io (Yan Li) Date: Tue, 21 Mar 2017 12:43:30 -0700 Subject: [lustre-devel] [PATCH 3/6] RLQOS main data structure In-Reply-To: References: Message-ID: Each client_obd maintains a qos data structure. Signed-off-by: Yan Li --- lustre/include/obd.h | 8 +++ lustre/include/rlqos.h | 136 +++++++++++++++++++++++++++++++++++++++++++++++ lustre/obdclass/genops.c | 25 +++++++++ 3 files changed, 169 insertions(+) create mode 100644 lustre/include/rlqos.h diff --git a/lustre/include/obd.h b/lustre/include/obd.h index b4ee379..726493c 100644 --- a/lustre/include/obd.h +++ b/lustre/include/obd.h @@ -50,6 +50,9 @@ #include #include #include +#ifdef ENABLE_RLQOS +# include "rlqos.h" +#endif #define MAX_OBD_DEVICES 8192 @@ -331,6 +334,11 @@ struct client_obd { void *cl_lru_work; /* hash tables for osc_quota_info */ struct cfs_hash *cl_quota_hash[LL_MAXQUOTAS]; + +#ifdef ENABLE_RLQOS + /* rate-limiting quality of service data */ + struct qos_data_t qos; +#endif }; #define obd2cli_tgt(obd) ((char *)(obd)->u.cli.cl_target_uuid.uuid) diff --git a/lustre/include/rlqos.h b/lustre/include/rlqos.h new file mode 100644 index 0000000..d8e012b --- /dev/null +++ b/lustre/include/rlqos.h @@ -0,0 +1,136 @@ +/* + * GPL HEADER START + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 only, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License version 2 for more details (a copy is included + * in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; If not, see + * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf + * + * Please contact Storage Systems Research Center, Computer Science Department, + * University of California, Santa Cruz (www.ssrc.ucsc.edu) if you need + * additional information or have any questions. + * + * GPL HEADER END + */ +/* + * Copyright (c) 2013-2017, University of California, Santa Cruz, CA, USA. + * All rights reserved. + */ +/* + * This file is part of Lustre, http://www.lustre.org/ + * Lustre is a trademark of Sun Microsystems, Inc. + * + * lustre/include/rlqos.h + */ + +#ifndef _RLQOS_H +#define _RLQOS_H + +/* We work with kernel only */ +#ifdef __KERNEL__ +# include +# include +# include +# include +# include +#else /* __KERNEL__ */ +# define HZ 100 +# define ONE_MILLION 1000000 +# include +#endif + +#define EWMA_ALPHA_INV (8) + +/** + * For tracking the exponentially-weighted moving average of a timeval. Note + * that we can't do float point div in kernel, so actually we are tracking + * ea = ewma * alpha. You should divide ea with alpha to get the real ewma. + */ +struct time_ewma { + __u64 alpha_inv; + __u64 ea; + struct timeval last_time; +}; +/* We can't do float point div, so we are tracking + * ea = ewma * alpha = ewma / alpha_inv + */ + +struct qos_rule_t { + __u64 ack_ewma_lower; + __u64 ack_ewma_upper; + __u64 send_ewma_lower; + __u64 send_ewma_upper; + unsigned int rtt_ratio100_lower; + unsigned int rtt_ratio100_upper; + int m100; + int b100; + unsigned int tau; + int used_times; + + __u64 ack_ewma_avg; + __u64 send_ewma_avg; + unsigned int rtt_ratio100_avg; +}; + +struct qos_data_t { + spinlock_t lock; + struct time_ewma ack_ewma; + struct time_ewma sent_ewma; + int rtt_ratio100; + long smallest_rtt; + int max_rpc_in_flight100; + struct timeval last_mrif_update_time; + int min_gap_between_updating_mrif; + int rule_no; + /* Following fields are for calculating I/O bandwidth, + * 0 for read, 1 for write */ + long last_req_sec[2]; /* second of last request we received */ + __u64 tp_last_sec[2]; /* throughput of last sec */ + __u64 sum_bytes_this_sec[2]; /* cumulative bytes read within this sec */ + /* For throttling support */ + unsigned int min_usec_between_rpcs; + struct timeval last_rpc_time; + struct qos_rule_t *rules; +}; + +static inline __u64 qos_get_ewma_usec(const struct time_ewma *ewma) { + return ewma->ea / ewma->alpha_inv; +} + +int parse_qos_rules(const char *buf, struct qos_data_t *qos); + +/* Lock of qos must be held. op == 0 for read, 1 for write */ +static inline void calc_throughput(struct qos_data_t *qos, int op, int bytes_transferred) +{ + struct timeval now; + + if (op != 0 && op != 1) + return; + + do_gettimeofday(&now); + if (likely(now.tv_sec == qos->last_req_sec[op])) { + qos->sum_bytes_this_sec[op] += bytes_transferred; + } else if (likely(now.tv_sec == qos->last_req_sec[op] + 1)) { + qos->tp_last_sec[op] = qos->sum_bytes_this_sec[op]; + qos->last_req_sec[op] = now.tv_sec; + qos->sum_bytes_this_sec[op] = bytes_transferred; + } else if (likely(now.tv_sec > qos->last_req_sec[op] + 1)) { + qos->tp_last_sec[op] = 0; + qos->last_req_sec[op] = now.tv_sec; + qos->sum_bytes_this_sec[op] = bytes_transferred; + } + /* Ignore cases when now.tv_sec < qos->last_req_sec */ +} + +#endif /* _RLQOS_H */ diff --git a/lustre/obdclass/genops.c b/lustre/obdclass/genops.c index a48f887..417c612 100644 --- a/lustre/obdclass/genops.c +++ b/lustre/obdclass/genops.c @@ -284,6 +284,28 @@ int class_unregister_type(const char *name) } /* class_unregister_type */ EXPORT_SYMBOL(class_unregister_type); +#ifdef ENABLE_RLQOS +static void init_time_ewma(struct time_ewma *ewma) +{ + ewma->alpha_inv = 8; + ewma->ea = 0; + ewma->last_time.tv_sec = 0; + ewma->last_time.tv_usec = 0; +} + +static void init_qos(struct client_obd *cli) +{ + struct qos_data_t *qos = &cli->qos; + + init_time_ewma(&qos->ack_ewma); + init_time_ewma(&qos->sent_ewma); + + spin_lock(&cli->cl_loi_list_lock); + qos->max_rpc_in_flight100 = cli->cl_max_rpcs_in_flight * 100; + spin_unlock(&cli->cl_loi_list_lock); +} +#endif + /** * Create a new obd device. * @@ -349,6 +371,9 @@ struct obd_device *class_newdev(const char *type_name, const char *name) result->obd_type = type; strncpy(result->obd_name, name, sizeof(result->obd_name) - 1); +#ifdef ENABLE_RLQOS + init_qos(&result->u.cli); +#endif obd_devs[i] = result; } } -- 1.8.3.1 From yanli at ascar.io Tue Mar 21 19:43:33 2017 From: yanli at ascar.io (Yan Li) Date: Tue, 21 Mar 2017 12:43:33 -0700 Subject: [lustre-devel] [PATCH 6/6] Adjust max_rpcs_in_flight according to metrics In-Reply-To: References: Message-ID: <65d90d71d2d0cd68642149cd2526d079594c2368.1490122510.git.yanli@ascar.io> Signed-off-by: Yan Li --- lustre/osc/osc_request.c | 165 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index c59c281..8efaf5a 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -1613,6 +1613,156 @@ static void osc_release_ppga(struct brw_page **ppga, size_t count) OBD_FREE(ppga, sizeof(*ppga) * count); } + +#ifdef ENABLE_RLQOS +/** + * te's lock should be acquired beforehand + */ +static void time_ewma_add_extlock(struct time_ewma *te, struct timeval *new_time) { + __u64 old_ea = te->ea; + long timediff; + + if (te->last_time.tv_sec != 0) { + timediff = cfs_timeval_sub(new_time, &te->last_time, NULL); + if (timediff < 0) { + CDEBUG(D_INFO, + "(te: %p) negative timediff %ld detected, using abs value\n", + te, timediff); + timediff = -timediff; + } + + /* Reset ea to 0 if a long gap (>10min) is detected */ + if (timediff > 10 * 60 * ONE_MILLION) { + CWARN("(te: %p) Long gap detected\n", te); + te->ea = 0; + } else { + /* ewma = ewma * (1-alpha) + amount * alpha + * ea = ewma * alpha, alpha_inv = 1/alpha + * + * ea = ea / alpha_inv * (alpha_inv - 1) + timediff + */ + do_div(te->ea, te->alpha_inv); + te->ea = te->ea * (te->alpha_inv - 1) + timediff; + if (te->ea > 1000000) { + CDEBUG(D_INFO, + "(te: %p) old_ea = %llu, " + "old_time = %ld.%ld, " + "new_time = %ld.%ld, new ea = %llu\n", + te, old_ea, + te->last_time.tv_sec, + te->last_time.tv_usec, + new_time->tv_sec, + new_time->tv_usec, te->ea); + } + } + } else { + CDEBUG(D_INFO, "(te: %p) first call\n", te); + } + te->last_time = *new_time; +} + +/** + * Calculate ewma of time values. Long gaps will be ignored. + */ +static int qos_adjust(struct obd_device *obd, struct timeval *new_ack_time, + struct timeval *new_sent_time, int op, int bytes_transferred) +{ + struct client_obd *cli = &obd->u.cli; + struct qos_data_t *qos = &cli->qos; + struct time_ewma *ack_ewma_p = &qos->ack_ewma; + struct time_ewma *sent_ewma_p = &qos->sent_ewma; + __u64 ack_ewma; + __u64 sent_ewma; + struct qos_rule_t *r; + int new_mrif = -1; /* -1 means no change needed */ + int i; + struct timeval now; + long rtt; + int rtt_ratio100; + long usec_since_last_mrif_update; + + spin_lock(&qos->lock); + time_ewma_add_extlock(ack_ewma_p, new_ack_time); + ack_ewma = qos_get_ewma_usec(ack_ewma_p); + + time_ewma_add_extlock(sent_ewma_p, new_sent_time); + sent_ewma = qos_get_ewma_usec(sent_ewma_p); + + /* calculate rtt */ + do_gettimeofday(&now); + rtt = cfs_timeval_sub(&now, new_sent_time, NULL); + if (0 == qos->smallest_rtt || rtt < qos->smallest_rtt) { + qos->smallest_rtt = rtt; + } + rtt = rtt * 100; + rtt_ratio100 = rtt / qos->smallest_rtt; + qos->rtt_ratio100 = rtt_ratio100; + + /* Calculate throughput */ + calc_throughput(qos, op, bytes_transferred); + + /* Adjust max_rpc_in_flight according to ack_ewma and send_ewma */ + if (NULL == qos->rules) goto out; + if (NULL == cli->cl_import) goto out; /* or else LPROCFS_CLIMP_CHECK may return this function, leaving qos->lock locked */ + for(i = 0; i < qos->rule_no; ++i) { + r = &qos->rules[i]; + if (ack_ewma >= r->ack_ewma_lower && + ack_ewma < r->ack_ewma_upper && + sent_ewma >= r->send_ewma_lower && + sent_ewma < r->send_ewma_upper && + rtt_ratio100 >= r->rtt_ratio100_lower && + rtt_ratio100 < r->rtt_ratio100_upper) + { + r->used_times++; + r->ack_ewma_avg += ((__s64)ack_ewma - (__s64)r->ack_ewma_avg) / r->used_times; + r->send_ewma_avg += ((__s64)sent_ewma - (__s64)r->send_ewma_avg) / r->used_times; + r->rtt_ratio100_avg += (rtt_ratio100 - (int)r->rtt_ratio100_avg) / r->used_times; + + usec_since_last_mrif_update = cfs_timeval_sub(&now, &qos->last_mrif_update_time, NULL); + if (usec_since_last_mrif_update > 0 && + usec_since_last_mrif_update >= qos->min_gap_between_updating_mrif) { + qos->last_mrif_update_time = now; + /* m100 is disabled when assigned negative values */ + if (r->m100 >= 0) { + /* Must multiply m100 first, then div by 100 to avoid + * losing precision */ + qos->max_rpc_in_flight100 *= r->m100; + qos->max_rpc_in_flight100 /= 100; + } + qos->max_rpc_in_flight100 += r->b100; + CDEBUG(D_INFO, "New max_rpc_in_flight100 = %d\n", qos->max_rpc_in_flight100); + if (qos->max_rpc_in_flight100 < 0) { + CDEBUG(D_INFO, "New max_rpc_in_flight100 is negative, reset it to 0\n"); + qos->max_rpc_in_flight100 = 0; + } + if (qos->max_rpc_in_flight100 > OSC_MAX_RIF_MAX * 100) { + CDEBUG(D_INFO, "New max_rpc_in_flight100 is larger than %d, reset it to max allowed value\n", OSC_MAX_RIF_MAX * 100); + qos->max_rpc_in_flight100 = OSC_MAX_RIF_MAX * 100; + } + new_mrif = qos->max_rpc_in_flight100 / 100; + if (new_mrif < 1) { + CDEBUG(D_INFO, "New max_rpc_in_flight is smaller than 1, reset it to 1\n"); + new_mrif = 1; + } + } + /* Update min_usec_between_rpcs to tau */ + qos->min_usec_between_rpcs = r->tau; + /* set MRIF after unlocking qos->lock to prevent deadlocking */ + break; + } + } +out: + spin_unlock(&qos->lock); + + if (-1 != new_mrif) { /* -1 means no change needed */ + LPROCFS_CLIMP_CHECK(obd); + set_max_rpcs_in_flight(new_mrif, cli); + LPROCFS_CLIMP_EXIT(obd); + } + return 0; +} +#endif /* ENABLE_RLQOS */ + static int brw_interpret(const struct lu_env *env, struct ptlrpc_request *req, void *data, int rc) { @@ -1622,6 +1772,14 @@ static int brw_interpret(const struct lu_env *env, struct client_obd *cli = aa->aa_cli; ENTRY; +#ifdef ENABLE_RLQOS + qos_adjust(req->rq_import->imp_obd, + &req->rq_arrival_time, + &aa->aa_oa->o_sent_time, + lustre_msg_get_opc(req->rq_reqmsg) - OST_READ, + req->rq_bulk->bd_nob_transferred); +#endif + rc = osc_brw_fini_request(req, rc); CDEBUG(D_INODE, "request %p aa %p rc %d\n", req, aa, rc); /* When server return -EINPROGRESS, client should always retry @@ -1874,6 +2032,10 @@ int osc_build_rpc(const struct lu_env *env, struct client_obd *cli, list_splice_init(&rpc_list, &aa->aa_oaps); INIT_LIST_HEAD(&aa->aa_exts); list_splice_init(ext_list, &aa->aa_exts); +#ifdef ENABLE_RLQOS + /* sent_time is used by RLQoS */ + do_gettimeofday(&aa->aa_oa->o_sent_time); +#endif spin_lock(&cli->cl_loi_list_lock); starting_offset >>= PAGE_SHIFT; @@ -1897,6 +2059,9 @@ int osc_build_rpc(const struct lu_env *env, struct client_obd *cli, cli->cl_w_in_flight); OBD_FAIL_TIMEOUT(OBD_FAIL_OSC_DELAY_IO, cfs_fail_val); +#ifdef ENABLE_RLQOS + qos_throttle(&cli->qos); +#endif ptlrpcd_add_req(req); rc = 0; EXIT; -- 1.8.3.1 From bevans at cray.com Tue Mar 21 20:09:26 2017 From: bevans at cray.com (Ben Evans) Date: Tue, 21 Mar 2017 20:09:26 +0000 Subject: [lustre-devel] [PATCH 1/6] Autoconf option for rate-limiting Quality of Service (RLQOS) In-Reply-To: <99fe8fdaaaa5b6fd36c0782269bc45a580079696.1490122510.git.yanli@ascar.io> References: <99fe8fdaaaa5b6fd36c0782269bc45a580079696.1490122510.git.yanli@ascar.io> Message-ID: I would remove the #ifdef ENABLE_RLQOS blocks, especially in lustre_idl.h since you're proposing to add new fields and consume some of the padding bits. It will cause a lot of headache for the next feature that comes along and consumes some of those bits. -Ben Evans On 3/21/17, 3:43 PM, "lustre-devel on behalf of Yan Li" wrote: >This patch enables rate-limiting quality of service (RLQOS) support as >talked in the ASCAR paper [1]. The purpose of RLQOS is to provide a >client-side rate limiting mechanism that controls max_rpcs_in_flight >and minimal gap between brw RPC requests (called tau in the code and >paper). > >RLQOS can be enabled by passing --enable-rlqos to configure. It then >can be controlled by tunables in procfs of each osc. > >[1] http://storageconference.us/2015/Papers/14.Li.pdf > >Signed-off-by: Yan Li >--- > lustre/autoconf/lustre-core.m4 | 17 +++++++++++++++++ > lustre/include/Makefile.am | 3 ++- > 2 files changed, 19 insertions(+), 1 deletion(-) > >diff --git a/lustre/autoconf/lustre-core.m4 >b/lustre/autoconf/lustre-core.m4 >index 0578325..7f1828e 100644 >--- a/lustre/autoconf/lustre-core.m4 >+++ b/lustre/autoconf/lustre-core.m4 >@@ -369,6 +369,22 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([ > AC_MSG_RESULT([$enable_ssk]) > ]) # LC_OPENSSL_SSK > >+# >+# LC_CONFIG_RLQOS >+# >+# Rate-limiting Quality of Service support >+# >+AC_DEFUN([LC_CONFIG_RLQOS], [ >+AC_MSG_CHECKING([whether to enable rate-limiting quality of service >support]) >+AC_ARG_ENABLE([rlqos], >+ AC_HELP_STRING([--enable-rlqos], >+ [enable rate-limiting quality of service support]), >+ [], [enable_rlqos="no"]) >+AC_MSG_RESULT([$enable_rlqos]) >+AS_IF([test "x$enable_rlqos" != xno], >+ [AC_DEFINE(ENABLE_RLQOS, 1, [enable rate-limiting quality of service >support])]) >+]) # LC_CONFIG_RLQOS >+ > # LC_INODE_PERMISION_2ARGS > # > # up to v2.6.27 had a 3 arg version (inode, mask, nameidata) >@@ -2241,6 +2257,7 @@ AC_DEFUN([LC_PROG_LINUX], [ > LC_GLIBC_SUPPORT_FHANDLES > LC_CONFIG_GSS > LC_OPENSSL_SSK >+ LC_CONFIG_RLQOS > > # 2.6.32 > LC_BLK_QUEUE_MAX_SEGMENTS >diff --git a/lustre/include/Makefile.am b/lustre/include/Makefile.am >index 9074ca4..6d72b6e 100644 >--- a/lustre/include/Makefile.am >+++ b/lustre/include/Makefile.am >@@ -98,4 +98,5 @@ EXTRA_DIST = \ > upcall_cache.h \ > lustre_kernelcomm.h \ > seq_range.h \ >- uapi_kernelcomm.h >+ uapi_kernelcomm.h \ >+ rlqos.h >-- >1.8.3.1 > >_______________________________________________ >lustre-devel mailing list >lustre-devel at lists.lustre.org >http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org From julia.lawall at lip6.fr Wed Mar 22 10:23:27 2017 From: julia.lawall at lip6.fr (Julia Lawall) Date: Wed, 22 Mar 2017 11:23:27 +0100 (CET) Subject: [lustre-devel] [Outreachy kernel] [PATCH] staging: media: Replace a bit shift by a use of BIT. In-Reply-To: <20170322042028.GA22848@arushi-HP-Pavilion-Notebook> References: <20170322042028.GA22848@arushi-HP-Pavilion-Notebook> Message-ID: On Wed, 22 Mar 2017, Arushi Singhal wrote: > This patch replaces bit shifting on 1 with the BIT(x) macro. > This was done with coccinelle: > @@ > constant c; > @@ > > -1 << c > +BIT(c) > > Signed-off-by: Arushi Singhal > --- > drivers/staging/octeon/ethernet-tx.c | 4 ++-- What is the connection to media? You also seem to have picked up the Lustre maintainers, who are not relevant. julia > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/staging/octeon/ethernet-tx.c b/drivers/staging/octeon/ethernet-tx.c > index ff4119e8de42..f00186ac4e27 100644 > --- a/drivers/staging/octeon/ethernet-tx.c > +++ b/drivers/staging/octeon/ethernet-tx.c > @@ -381,7 +381,7 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev) > (ip_hdr(skb)->version == 4) && > (ip_hdr(skb)->ihl == 5) && > ((ip_hdr(skb)->frag_off == 0) || > - (ip_hdr(skb)->frag_off == htons(1 << 14))) && > + (ip_hdr(skb)->frag_off == htons(BIT(14)))) && > ((ip_hdr(skb)->protocol == IPPROTO_TCP) || > (ip_hdr(skb)->protocol == IPPROTO_UDP))) { > /* Use hardware checksum calc */ > @@ -613,7 +613,7 @@ int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev) > #endif > work->word2.s.is_frag = !((ip_hdr(skb)->frag_off == 0) || > (ip_hdr(skb)->frag_off == > - 1 << 14)); > + BIT(14))); > #if 0 > /* Assume Linux is sending a good packet */ > work->word2.s.IP_exc = 0; > -- > 2.11.0 > > -- > You received this message because you are subscribed to the Google Groups "outreachy-kernel" group. > To unsubscribe from this group and stop receiving emails from it, send an email to outreachy-kernel+unsubscribe at googlegroups.com. > To post to this group, send email to outreachy-kernel at googlegroups.com. > To view this discussion on the web visit https://groups.google.com/d/msgid/outreachy-kernel/20170322042028.GA22848%40arushi-HP-Pavilion-Notebook. > For more options, visit https://groups.google.com/d/optout. > From andreas.dilger at intel.com Wed Mar 22 12:12:11 2017 From: andreas.dilger at intel.com (Dilger, Andreas) Date: Wed, 22 Mar 2017 12:12:11 +0000 Subject: [lustre-devel] [PATCH] staging: lustre: Replace a bit shift by a use of BIT. In-Reply-To: <20170322023933.GA11339@arushi-HP-Pavilion-Notebook> References: <20170322023933.GA11339@arushi-HP-Pavilion-Notebook> Message-ID: On Mar 21, 2017, at 22:39, Arushi Singhal wrote: > > This patch replaces bit shifting on 1 with the BIT(x) macro. > This was done with coccinelle: > @@ > constant c; > @@ > > -1 << c > +BIT(c) Did you take the time to look at what this Coccinelle script actually did, to see if it actually makes sense? Some of the cases where this replacement was done makes sense because a specific bit is being accessed (i.e. a bitmask). Elsewhere, it doesn't make sense to use BIT() to specify numeric values (e.g. PAGE_SHIFT, 1 << 12 = 1024, etc) since they are not bitmasks. > Signed-off-by: Arushi Singhal > --- > drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 2 +- > drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c | 8 ++++---- > drivers/staging/lustre/lnet/klnds/socklnd/socklnd_modparams.c | 2 +- > drivers/staging/lustre/lnet/lnet/lib-ptl.c | 4 ++-- > drivers/staging/lustre/lnet/lnet/net_fault.c | 8 ++++---- > drivers/staging/lustre/lustre/llite/lproc_llite.c | 4 ++-- > drivers/staging/lustre/lustre/obdclass/lustre_handles.c | 2 +- > drivers/staging/lustre/lustre/osc/osc_request.c | 2 +- > 8 files changed, 16 insertions(+), 16 deletions(-) > > diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > index 79321e4aaf30..449f04f125b7 100644 > --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > @@ -2241,7 +2241,7 @@ static int kiblnd_hdev_get_attr(struct kib_hca_dev *hdev) > * matching that of the native system > */ > hdev->ibh_page_shift = PAGE_SHIFT; > - hdev->ibh_page_size = 1 << PAGE_SHIFT; > + hdev->ibh_page_size = BIT(PAGE_SHIFT); This should just be replaced with "PAGE_SIZE". > hdev->ibh_page_mask = ~((__u64)hdev->ibh_page_size - 1); > > hdev->ibh_mr_size = hdev->ibh_ibdev->attrs.max_mr_size; > diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c > index eaa4399e6a2e..5bef8a7e053b 100644 > --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c > +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c > @@ -1906,14 +1906,14 @@ ksocknal_connect(struct ksock_route *route) > if (retry_later) /* needs reschedule */ > break; > > - if (wanted & (1 << SOCKLND_CONN_ANY)) { > + if (wanted & (BIT(SOCKLND_CONN_ANY))) { There shouldn't be any need to put parenthesis around (BIT(x)) here, or any of the cases below, or the BIT macro is broken. But besides that, the use of BIT() here looks OK. > type = SOCKLND_CONN_ANY; > - } else if (wanted & (1 << SOCKLND_CONN_CONTROL)) { > + } else if (wanted & (BIT(SOCKLND_CONN_CONTROL))) { > type = SOCKLND_CONN_CONTROL; > - } else if (wanted & (1 << SOCKLND_CONN_BULK_IN)) { > + } else if (wanted & (BIT(SOCKLND_CONN_BULK_IN))) { > type = SOCKLND_CONN_BULK_IN; > } else { > - LASSERT(wanted & (1 << SOCKLND_CONN_BULK_OUT)); > + LASSERT(wanted & (BIT(SOCKLND_CONN_BULK_OUT))); > type = SOCKLND_CONN_BULK_OUT; > } > > diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_modparams.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_modparams.c > index fc7eec83ac07..2d1e3479cf7e 100644 > --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_modparams.c > +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_modparams.c > @@ -71,7 +71,7 @@ static int typed_conns = 1; > module_param(typed_conns, int, 0444); > MODULE_PARM_DESC(typed_conns, "use different sockets for bulk"); > > -static int min_bulk = 1 << 10; > +static int min_bulk = BIT(10); This is a scalar value and not a bitmask. It could just be "1024", but using BIT() is not correct. > module_param(min_bulk, int, 0644); > MODULE_PARM_DESC(min_bulk, "smallest 'large' message"); > > diff --git a/drivers/staging/lustre/lnet/lnet/lib-ptl.c b/drivers/staging/lustre/lnet/lnet/lib-ptl.c > index 63cce0c4a065..b980c669705e 100644 > --- a/drivers/staging/lustre/lnet/lnet/lib-ptl.c > +++ b/drivers/staging/lustre/lnet/lnet/lib-ptl.c > @@ -332,7 +332,7 @@ lnet_mt_test_exhausted(struct lnet_match_table *mtable, int pos) > LASSERT(pos <= LNET_MT_HASH_IGNORE); > /* mtable::mt_mhash[pos] is marked as exhausted or not */ > bmap = &mtable->mt_exhausted[pos >> LNET_MT_BITS_U64]; > - pos &= (1 << LNET_MT_BITS_U64) - 1; > + pos &= (BIT(LNET_MT_BITS_U64)) - 1; The use of BIT() above is probably not correct. This is creating a mask to align pos to a multiple of (1 << LNET_MT_BITS_U64), and IMHO BIT() shouldn't be used just any time a value is being shifted but rather only when a one-bit mask is needed. Conversely, the below usage could be converted to use the macro since this is actually a bitmask: return *bmap & BIT(pos); > return (*bmap & (1ULL << pos)); > } > @@ -347,7 +347,7 @@ lnet_mt_set_exhausted(struct lnet_match_table *mtable, int pos, int exhausted) > > /* set mtable::mt_mhash[pos] as exhausted/non-exhausted */ > bmap = &mtable->mt_exhausted[pos >> LNET_MT_BITS_U64]; > - pos &= (1 << LNET_MT_BITS_U64) - 1; > + pos &= (BIT(LNET_MT_BITS_U64)) - 1; > > if (!exhausted) > *bmap &= ~(1ULL << pos); Ditto. > diff --git a/drivers/staging/lustre/lnet/lnet/net_fault.c b/drivers/staging/lustre/lnet/lnet/net_fault.c > index 18183cbb9859..e83761a77d22 100644 > --- a/drivers/staging/lustre/lnet/lnet/net_fault.c > +++ b/drivers/staging/lustre/lnet/lnet/net_fault.c > @@ -997,10 +997,10 @@ lnet_fault_ctl(int opc, struct libcfs_ioctl_data *data) > int > lnet_fault_init(void) > { > - BUILD_BUG_ON(LNET_PUT_BIT != 1 << LNET_MSG_PUT); > - BUILD_BUG_ON(LNET_ACK_BIT != 1 << LNET_MSG_ACK); > - BUILD_BUG_ON(LNET_GET_BIT != 1 << LNET_MSG_GET); > - BUILD_BUG_ON(LNET_REPLY_BIT != 1 << LNET_MSG_REPLY); > + BUILD_BUG_ON(LNET_PUT_BIT != BIT(LNET_MSG_PUT)); > + BUILD_BUG_ON(LNET_ACK_BIT != BIT(LNET_MSG_ACK)); > + BUILD_BUG_ON(LNET_GET_BIT != BIT(LNET_MSG_GET)); > + BUILD_BUG_ON(LNET_REPLY_BIT != BIT(LNET_MSG_REPLY)); This looks reasonable at first glance, though on further thought it seems kind of pointless since this is really: #defined LET_PUT_BIT BIT(LNET_MSG_PUT) BUILD_BUG_ON(BIT(LNET_MSG_PUT) != BIT(LNET_MSG_PUT)) so it is just checking that the macro's value is the same when called two times. I'd suggest just getting rid of these BUILD_BUG_ON() checks completely > diff --git a/drivers/staging/lustre/lustre/llite/lproc_llite.c b/drivers/staging/lustre/lustre/llite/lproc_llite.c > index 40f1fcf8b5c0..366833dd8aa3 100644 > --- a/drivers/staging/lustre/lustre/llite/lproc_llite.c > +++ b/drivers/staging/lustre/lustre/llite/lproc_llite.c > @@ -1308,7 +1308,7 @@ static void ll_display_extents_info(struct ll_rw_extents_info *io_extents, > r, pct(r, read_tot), pct(read_cum, read_tot), > w, pct(w, write_tot), pct(write_cum, write_tot)); > start = end; > - if (start == 1 << 10) { > + if (start == BIT(10)) { This should just be 1024, or could be left as-is left as-is. > start = 1; > units += 10; > unitp++; > @@ -1506,7 +1506,7 @@ void ll_rw_stats_tally(struct ll_sb_info *sbi, pid_t pid, > lprocfs_oh_clear(&io_extents->pp_extents[cur].pp_w_hist); > } > > - for (i = 0; (count >= (1 << LL_HIST_START << i)) && > + for (i = 0; (count >= (BIT(LL_HIST_START) << i)) && This is also not a bitmask, but rather a scalar value. > (i < (LL_HIST_MAX - 1)); i++) > ; > if (rw == 0) { > diff --git a/drivers/staging/lustre/lustre/obdclass/lustre_handles.c b/drivers/staging/lustre/lustre/obdclass/lustre_handles.c > index c9445e5ec271..11e32b5174f2 100644 > --- a/drivers/staging/lustre/lustre/obdclass/lustre_handles.c > +++ b/drivers/staging/lustre/lustre/obdclass/lustre_handles.c > @@ -49,7 +49,7 @@ static struct handle_bucket { > struct list_head head; > } *handle_hash; > > -#define HANDLE_HASH_SIZE (1 << 16) > +#define HANDLE_HASH_SIZE (BIT(16)) Also not a bitmask, but a scalar value. > #define HANDLE_HASH_MASK (HANDLE_HASH_SIZE - 1) > > /* > diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c > index d8aa3fb468c7..8739abf639a7 100644 > --- a/drivers/staging/lustre/lustre/osc/osc_request.c > +++ b/drivers/staging/lustre/lustre/osc/osc_request.c > @@ -2847,7 +2847,7 @@ static int __init osc_init(void) > register_shrinker(&osc_cache_shrinker); > > /* This is obviously too much memory, only prevent overflow here */ > - if (osc_reqpool_mem_max >= 1 << 12 || osc_reqpool_mem_max == 0) { > + if (osc_reqpool_mem_max >= BIT(12) || osc_reqpool_mem_max == 0) { Also a scalar value. Could be 4096. Cheers, Andreas From yanli at ascar.io Wed Mar 22 14:19:51 2017 From: yanli at ascar.io (Yan Li) Date: Wed, 22 Mar 2017 07:19:51 -0700 Subject: [lustre-devel] [PATCH 1/6] Autoconf option for rate-limiting Quality of Service (RLQOS) In-Reply-To: References: <99fe8fdaaaa5b6fd36c0782269bc45a580079696.1490122510.git.yanli@ascar.io> Message-ID: On 03/21/2017 01:09 PM, Ben Evans wrote: > I would remove the #ifdef ENABLE_RLQOS blocks, especially in lustre_idl.h > since you're proposing to add new fields and consume some of the padding > bits. It will cause a lot of headache for the next feature that comes > along and consumes some of those bits. Yeah, that's a good point. I'll remove it if all are ok with this. Yan From bevans at cray.com Wed Mar 22 14:27:25 2017 From: bevans at cray.com (Ben Evans) Date: Wed, 22 Mar 2017 14:27:25 +0000 Subject: [lustre-devel] [PATCH 1/6] Autoconf option for rate-limiting Quality of Service (RLQOS) In-Reply-To: References: <99fe8fdaaaa5b6fd36c0782269bc45a580079696.1490122510.git.yanli@ascar.io> Message-ID: I'd get rid of all the ENABLE_RLQOS blocks myself, but minimally the lustre_idl.h ones. -Ben Evans On 3/22/17, 10:19 AM, "Yan Li" wrote: > >On 03/21/2017 01:09 PM, Ben Evans wrote: >> I would remove the #ifdef ENABLE_RLQOS blocks, especially in >>lustre_idl.h >> since you're proposing to add new fields and consume some of the padding >> bits. It will cause a lot of headache for the next feature that comes >> along and consumes some of those bits. > >Yeah, that's a good point. I'll remove it if all are ok with this. > >Yan From alexey.lyashkov at seagate.com Thu Mar 23 14:03:36 2017 From: alexey.lyashkov at seagate.com (Alexey Lyashkov) Date: Thu, 23 Mar 2017 17:03:36 +0300 Subject: [lustre-devel] [PATCH 5/6] Throttle the outgoing requests according to tau In-Reply-To: <613cd7339035952e7f4dce3aa9f3db9e8bb52c92.1490122510.git.yanli@ascar.io> References: <613cd7339035952e7f4dce3aa9f3db9e8bb52c92.1490122510.git.yanli@ascar.io> Message-ID: I dislike a sleep in this code. I think you should use req->rq_sent time to have a some delay, as way as osc redo code does. ptlrpc_check_set() .. /* delayed send - skip */ if (req->rq_phase == RQ_PHASE_NEW && req->rq_sent) continue; On Tue, Mar 21, 2017 at 10:43 PM, Yan Li wrote: > Signed-off-by: Yan Li > --- > lustre/osc/osc_cache.c | 3 +++ > lustre/osc/osc_internal.h | 66 ++++++++++++++++++++++++++++++ > +++++++++++++++++ > 2 files changed, 69 insertions(+) > > diff --git a/lustre/osc/osc_cache.c b/lustre/osc/osc_cache.c > index 236263c..2f9d4e1 100644 > --- a/lustre/osc/osc_cache.c > +++ b/lustre/osc/osc_cache.c > @@ -2316,6 +2316,9 @@ static int osc_io_unplug0(const struct lu_env *env, > struct client_obd *cli, > } else { > CDEBUG(D_CACHE, "Queue writeback work for client %p.\n", > cli); > LASSERT(cli->cl_writeback_work != NULL); > +#ifdef ENABLE_RLQOS > + qos_throttle(&cli->qos); > +#endif > rc = ptlrpcd_queue_work(cli->cl_writeback_work); > } > return rc; > diff --git a/lustre/osc/osc_internal.h b/lustre/osc/osc_internal.h > index 06c21b3..d31d5ba 100644 > --- a/lustre/osc/osc_internal.h > +++ b/lustre/osc/osc_internal.h > @@ -245,4 +245,70 @@ extern unsigned long osc_cache_shrink_count(struct > shrinker *sk, > extern unsigned long osc_cache_shrink_scan(struct shrinker *sk, > struct shrink_control *sc); > > +#ifdef ENABLE_RLQOS > +static inline void qos_throttle(struct qos_data_t *qos) > +{ > + struct timeval now; > + long usec_since_last_rpc; > + long need_sleep_usec = 0; > + > + spin_lock(&qos->lock); > + if (0 == qos->min_usec_between_rpcs) > + goto out; > + > + do_gettimeofday(&now); > + usec_since_last_rpc = cfs_timeval_sub(&now, &qos->last_rpc_time, > NULL); > + if (usec_since_last_rpc < 0) { > + usec_since_last_rpc = 0; > + } > + if (usec_since_last_rpc < qos->min_usec_between_rpcs) { > + need_sleep_usec = qos->min_usec_between_rpcs - > usec_since_last_rpc; > + } > + qos->last_rpc_time = now; > +out: > + spin_unlock(&qos->lock); > + if (0 == need_sleep_usec) { > + return; > + } > + > + /* About timer ranges: > + Ref: https://urldefense.proofpoint.com/v2/url?u=https-3A__www. > kernel.org_doc_Documentation_timers_timers-2Dhowto.txt&d= > DwICAg&c=IGDlg0lD0b-nebmJJ0Kp8A&r=m8P9AM2wTf4l79yg9e1LHD5IHagtwa > 3P4AXaemlM6Lg&m=w0oijGmz2ea38--CHGZq4fPu44dwEldJr2BDVZcBR2U& > s=jN5WjVQ8jELL9iEXADWoal4-Yo76FIU3VVDcdN3zsC4&e= */ > + if (need_sleep_usec < 1000) { > + udelay(need_sleep_usec); > + } else if (need_sleep_usec < 20000) { > + usleep_range(need_sleep_usec - 1, need_sleep_usec); > + } else { > + msleep(need_sleep_usec / 1000); > + } > +} > +#endif /* ENABLE_RLQOS */ > + > +/* You must call LPROCFS_CLIMP_CHECK() on the obd device before and > + * LPROCFS_CLIMP_EXIT() after calling this function. They are not called > inside > + * this function, because they may return an error code. > + */ > +static inline void set_max_rpcs_in_flight(int val, struct client_obd *cli) > +{ > + int adding, added, req_count; > + > + adding = val - cli->cl_max_rpcs_in_flight; > + req_count = atomic_read(&osc_pool_req_count); > + if (adding > 0 && req_count < osc_reqpool_maxreqcount) { > + /* > + * There might be some race which will cause over-limit > + * allocation, but it is fine. > + */ > + if (req_count + adding > osc_reqpool_maxreqcount) > + adding = osc_reqpool_maxreqcount - req_count; > + > + added = osc_rq_pool->prp_populate(osc_rq_pool, adding); > + atomic_add(added, &osc_pool_req_count); > + } > + > + spin_lock(&cli->cl_loi_list_lock); > + cli->cl_max_rpcs_in_flight = val; > + client_adjust_max_dirty(cli); > + spin_unlock(&cli->cl_loi_list_lock); > +} > + > #endif /* OSC_INTERNAL_H */ > -- > 1.8.3.1 > > _______________________________________________ > lustre-devel mailing list > lustre-devel at lists.lustre.org > https://urldefense.proofpoint.com/v2/url?u=http-3A__lists. > lustre.org_listinfo.cgi_lustre-2Ddevel-2Dlustre.org&d=DwICAg&c=IGDlg0lD0b- > nebmJJ0Kp8A&r=m8P9AM2wTf4l79yg9e1LHD5IHagtwa3P4AXaemlM6Lg&m=w0oijGmz2ea38- > -CHGZq4fPu44dwEldJr2BDVZcBR2U&s=ppAA2u9phKTaqwpnFsNVQGtqbG3xF6 > tk4_Q9mVL_lGk&e= > -- Alexey Lyashkov *·* Technical lead for a Morpheus team Seagate Technology, LLC www.seagate.com www.lustre.org -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexey.lyashkov at seagate.com Thu Mar 23 14:54:07 2017 From: alexey.lyashkov at seagate.com (Alexey Lyashkov) Date: Thu, 23 Mar 2017 17:54:07 +0300 Subject: [lustre-devel] [PATCH 2/6] Added fields to message for RLQOS support In-Reply-To: <28c79a11bf7df97be1d3355b83c55a4ceea177bc.1490122510.git.yanli@ascar.io> References: <28c79a11bf7df97be1d3355b83c55a4ceea177bc.1490122510.git.yanli@ascar.io> Message-ID: You should don't comment a asserts, but introduce an additional connect flag to handle used fields if this flag set. As i see you have write an code to work between patched nodes, but we have no guaratee all nodes in clusters uses same version all time. On Tue, Mar 21, 2017 at 10:43 PM, Yan Li wrote: > Modified the request message to embed sent_time, which will be > returned from the server and used to calculate the exponentially > weighted moving average of sent_time gap in return messages. It is > used as a metric for rate-limiting quality of service. > > Signed-off-by: Yan Li > --- > lustre/include/lustre/lustre_idl.h | 4 ++++ > lustre/ptlrpc/pack_generic.c | 5 +++++ > lustre/ptlrpc/wiretest.c | 2 ++ > lustre/utils/wiretest.c | 2 ++ > 4 files changed, 13 insertions(+) > > diff --git a/lustre/include/lustre/lustre_idl.h b/lustre/include/lustre/ > lustre_idl.h > index bf23a47..7a200d1 100644 > --- a/lustre/include/lustre/lustre_idl.h > +++ b/lustre/include/lustre/lustre_idl.h > @@ -3336,8 +3336,12 @@ struct obdo { > * each stripe. > * brw: grant space > consumed on > * the client for the > write */ > +#ifdef ENABLE_RLQOS > + struct timeval o_sent_time; /* timeval is 64x2 bits on > Linux */ > +#else > __u64 o_padding_4; > __u64 o_padding_5; > +#endif > __u64 o_padding_6; > }; > > diff --git a/lustre/ptlrpc/pack_generic.c b/lustre/ptlrpc/pack_generic.c > index 8df8ea8..d0bc87a 100644 > --- a/lustre/ptlrpc/pack_generic.c > +++ b/lustre/ptlrpc/pack_generic.c > @@ -1722,8 +1722,13 @@ void lustre_swab_obdo (struct obdo *o) > __swab32s (&o->o_uid_h); > __swab32s (&o->o_gid_h); > __swab64s (&o->o_data_version); > +#ifdef ENABLE_RLQOS > + __swab64s ((__u64*)&o->o_sent_time.tv_sec); > + __swab64s ((__u64*)&o->o_sent_time.tv_usec); > +#else > CLASSERT(offsetof(typeof(*o), o_padding_4) != 0); > CLASSERT(offsetof(typeof(*o), o_padding_5) != 0); > +#endif > CLASSERT(offsetof(typeof(*o), o_padding_6) != 0); > > } > diff --git a/lustre/ptlrpc/wiretest.c b/lustre/ptlrpc/wiretest.c > index 070ef91..0c909a6 100644 > --- a/lustre/ptlrpc/wiretest.c > +++ b/lustre/ptlrpc/wiretest.c > @@ -1314,6 +1314,7 @@ void lustre_assert_wire_constants(void) > (long long)(int)offsetof(struct obdo, o_data_version)); > LASSERTF((int)sizeof(((struct obdo *)0)->o_data_version) == 8, > "found %lld\n", > (long long)(int)sizeof(((struct obdo > *)0)->o_data_version)); > +#ifndef ENABLE_RLQOS > LASSERTF((int)offsetof(struct obdo, o_padding_4) == 184, "found > %lld\n", > (long long)(int)offsetof(struct obdo, o_padding_4)); > LASSERTF((int)sizeof(((struct obdo *)0)->o_padding_4) == 8, "found > %lld\n", > @@ -1322,6 +1323,7 @@ void lustre_assert_wire_constants(void) > (long long)(int)offsetof(struct obdo, o_padding_5)); > LASSERTF((int)sizeof(((struct obdo *)0)->o_padding_5) == 8, "found > %lld\n", > (long long)(int)sizeof(((struct obdo *)0)->o_padding_5)); > +#endif > LASSERTF((int)offsetof(struct obdo, o_padding_6) == 200, "found > %lld\n", > (long long)(int)offsetof(struct obdo, o_padding_6)); > LASSERTF((int)sizeof(((struct obdo *)0)->o_padding_6) == 8, "found > %lld\n", > diff --git a/lustre/utils/wiretest.c b/lustre/utils/wiretest.c > index 233d7d8..47fbbf0 100644 > --- a/lustre/utils/wiretest.c > +++ b/lustre/utils/wiretest.c > @@ -1329,6 +1329,7 @@ void lustre_assert_wire_constants(void) > (long long)(int)offsetof(struct obdo, o_data_version)); > LASSERTF((int)sizeof(((struct obdo *)0)->o_data_version) == 8, > "found %lld\n", > (long long)(int)sizeof(((struct obdo > *)0)->o_data_version)); > +#ifndef ENABLE_RLQOS > LASSERTF((int)offsetof(struct obdo, o_padding_4) == 184, "found > %lld\n", > (long long)(int)offsetof(struct obdo, o_padding_4)); > LASSERTF((int)sizeof(((struct obdo *)0)->o_padding_4) == 8, "found > %lld\n", > @@ -1337,6 +1338,7 @@ void lustre_assert_wire_constants(void) > (long long)(int)offsetof(struct obdo, o_padding_5)); > LASSERTF((int)sizeof(((struct obdo *)0)->o_padding_5) == 8, "found > %lld\n", > (long long)(int)sizeof(((struct obdo *)0)->o_padding_5)); > +#endif > LASSERTF((int)offsetof(struct obdo, o_padding_6) == 200, "found > %lld\n", > (long long)(int)offsetof(struct obdo, o_padding_6)); > LASSERTF((int)sizeof(((struct obdo *)0)->o_padding_6) == 8, "found > %lld\n", > -- > 1.8.3.1 > > _______________________________________________ > lustre-devel mailing list > lustre-devel at lists.lustre.org > https://urldefense.proofpoint.com/v2/url?u=http-3A__lists. > lustre.org_listinfo.cgi_lustre-2Ddevel-2Dlustre.org&d=DwICAg&c=IGDlg0lD0b- > nebmJJ0Kp8A&r=m8P9AM2wTf4l79yg9e1LHD5IHagtwa3P4AXaemlM6Lg&m= > NuClc8LkPaQ91Zav0h5yoiRmBVC4_Ks9Db6KX3xsRmk&s= > 6FVNfemWTMvnOwmVBxixoJyS4CNIP_D14UGw2pWlGd0&e= > -- Alexey Lyashkov *·* Technical lead for a Morpheus team Seagate Technology, LLC www.seagate.com www.lustre.org -------------- next part -------------- An HTML attachment was scrubbed... URL: From andreas.dilger at intel.com Thu Mar 23 20:41:47 2017 From: andreas.dilger at intel.com (Dilger, Andreas) Date: Thu, 23 Mar 2017 20:41:47 +0000 Subject: [lustre-devel] [PATCH v2] staging: lustre: Replace a bit shift by a use of BIT. In-Reply-To: <20170322155333.GA17411@arushi-HP-Pavilion-Notebook> References: <20170322155333.GA17411@arushi-HP-Pavilion-Notebook> Message-ID: <1BE44C84-0DDB-4D9E-B4CB-C8A979F48EC6@intel.com> On Mar 22, 2017, at 09:53, Arushi Singhal wrote: > > This patch replaces bit shifting on 1 with the BIT(x) macro. > This was done with coccinelle: > @@ > constant c; > @@ > > -1 << c > +BIT(c) > > Signed-off-by: Arushi Singhal Reviewed-by: Andreas Dilger > --- > changes in v2 > - remove the unnecessary parenthesis. > - removethe wrong changes. > > drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c | 8 ++++---- > drivers/staging/lustre/lnet/lnet/lib-ptl.c | 2 +- > drivers/staging/lustre/lustre/llite/lproc_llite.c | 2 +- > 3 files changed, 6 insertions(+), 6 deletions(-) > > diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c > index eaa4399e6a2e..2b93ceaa2844 100644 > --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c > +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c > @@ -1906,14 +1906,14 @@ ksocknal_connect(struct ksock_route *route) > if (retry_later) /* needs reschedule */ > break; > > - if (wanted & (1 << SOCKLND_CONN_ANY)) { > + if (wanted & BIT(SOCKLND_CONN_ANY)) { > type = SOCKLND_CONN_ANY; > - } else if (wanted & (1 << SOCKLND_CONN_CONTROL)) { > + } else if (wanted & BIT(SOCKLND_CONN_CONTROL)) { > type = SOCKLND_CONN_CONTROL; > - } else if (wanted & (1 << SOCKLND_CONN_BULK_IN)) { > + } else if (wanted & BIT(SOCKLND_CONN_BULK_IN)) { > type = SOCKLND_CONN_BULK_IN; > } else { > - LASSERT(wanted & (1 << SOCKLND_CONN_BULK_OUT)); > + LASSERT(wanted & BIT(SOCKLND_CONN_BULK_OUT)); > type = SOCKLND_CONN_BULK_OUT; > } > > diff --git a/drivers/staging/lustre/lnet/lnet/lib-ptl.c b/drivers/staging/lustre/lnet/lnet/lib-ptl.c > index 63cce0c4a065..33332724ab94 100644 > --- a/drivers/staging/lustre/lnet/lnet/lib-ptl.c > +++ b/drivers/staging/lustre/lnet/lnet/lib-ptl.c > @@ -334,7 +334,7 @@ lnet_mt_test_exhausted(struct lnet_match_table *mtable, int pos) > bmap = &mtable->mt_exhausted[pos >> LNET_MT_BITS_U64]; > pos &= (1 << LNET_MT_BITS_U64) - 1; > > - return (*bmap & (1ULL << pos)); > + return (*bmap & BIT(pos)); > } > > static void > diff --git a/drivers/staging/lustre/lustre/llite/lproc_llite.c b/drivers/staging/lustre/lustre/llite/lproc_llite.c > index 40f1fcf8b5c0..c742cba60199 100644 > --- a/drivers/staging/lustre/lustre/llite/lproc_llite.c > +++ b/drivers/staging/lustre/lustre/llite/lproc_llite.c > @@ -1308,7 +1308,7 @@ static void ll_display_extents_info(struct ll_rw_extents_info *io_extents, > r, pct(r, read_tot), pct(read_cum, read_tot), > w, pct(w, write_tot), pct(write_cum, write_tot)); > start = end; > - if (start == 1 << 10) { > + if (start == 1024) { > start = 1; > units += 10; > unitp++; > -- > 2.11.0 > Cheers, Andreas -- Andreas Dilger Lustre Principal Architect Intel Corporation From andreas.dilger at intel.com Thu Mar 23 20:43:59 2017 From: andreas.dilger at intel.com (Dilger, Andreas) Date: Thu, 23 Mar 2017 20:43:59 +0000 Subject: [lustre-devel] [PATCH] staging: lustre: Replace a bit shift by a use of BIT. In-Reply-To: References: <20170322023933.GA11339@arushi-HP-Pavilion-Notebook> Message-ID: On Mar 22, 2017, at 06:12, Dilger, Andreas wrote: > > On Mar 21, 2017, at 22:39, Arushi Singhal wrote: >> >> This patch replaces bit shifting on 1 with the BIT(x) macro. >> This was done with coccinelle: [snip] >> diff --git a/drivers/staging/lustre/lnet/lnet/net_fault.c b/drivers/staging/lustre/lnet/lnet/net_fault.c >> index 18183cbb9859..e83761a77d22 100644 >> --- a/drivers/staging/lustre/lnet/lnet/net_fault.c >> +++ b/drivers/staging/lustre/lnet/lnet/net_fault.c >> @@ -997,10 +997,10 @@ lnet_fault_ctl(int opc, struct libcfs_ioctl_data *data) >> int >> lnet_fault_init(void) >> { >> - BUILD_BUG_ON(LNET_PUT_BIT != 1 << LNET_MSG_PUT); >> - BUILD_BUG_ON(LNET_ACK_BIT != 1 << LNET_MSG_ACK); >> - BUILD_BUG_ON(LNET_GET_BIT != 1 << LNET_MSG_GET); >> - BUILD_BUG_ON(LNET_REPLY_BIT != 1 << LNET_MSG_REPLY); >> + BUILD_BUG_ON(LNET_PUT_BIT != BIT(LNET_MSG_PUT)); >> + BUILD_BUG_ON(LNET_ACK_BIT != BIT(LNET_MSG_ACK)); >> + BUILD_BUG_ON(LNET_GET_BIT != BIT(LNET_MSG_GET)); >> + BUILD_BUG_ON(LNET_REPLY_BIT != BIT(LNET_MSG_REPLY)); > > This looks reasonable at first glance, though on further thought it seems kind of > pointless since this is really: > > #defined LET_PUT_BIT BIT(LNET_MSG_PUT) > > BUILD_BUG_ON(BIT(LNET_MSG_PUT) != BIT(LNET_MSG_PUT)) > > so it is just checking that the macro's value is the same when called two times. > I'd suggest just getting rid of these BUILD_BUG_ON() checks completely . Arushi, it would be great if you could submit a patch to remove the above BUILD_BUG_ON() lines completely. I don't think they have any value anymore. Cheers, Andreas -- Andreas Dilger Lustre Principal Architect Intel Corporation From gregkh at linuxfoundation.org Fri Mar 24 13:44:59 2017 From: gregkh at linuxfoundation.org (Greg Kroah-Hartman) Date: Fri, 24 Mar 2017 14:44:59 +0100 Subject: [lustre-devel] [PATCH] staging: lustre: Remove redundant code In-Reply-To: <20170324113952.GA31427@arushi-HP-Pavilion-Notebook> References: <20170324113952.GA31427@arushi-HP-Pavilion-Notebook> Message-ID: <20170324134459.GA26275@kroah.com> On Fri, Mar 24, 2017 at 05:09:53PM +0530, Arushi Singhal wrote: > Remove the code which do not have any value. > > Signed-off-by: Arushi Singhal > --- > drivers/staging/lustre/lnet/lnet/net_fault.c | 5 ----- > 1 file changed, 5 deletions(-) > > diff --git a/drivers/staging/lustre/lnet/lnet/net_fault.c b/drivers/staging/lustre/lnet/lnet/net_fault.c > index 18183cbb9859..b60261db9e67 100644 > --- a/drivers/staging/lustre/lnet/lnet/net_fault.c > +++ b/drivers/staging/lustre/lnet/lnet/net_fault.c > @@ -997,11 +997,6 @@ lnet_fault_ctl(int opc, struct libcfs_ioctl_data *data) > int > lnet_fault_init(void) > { > - BUILD_BUG_ON(LNET_PUT_BIT != 1 << LNET_MSG_PUT); > - BUILD_BUG_ON(LNET_ACK_BIT != 1 << LNET_MSG_ACK); > - BUILD_BUG_ON(LNET_GET_BIT != 1 << LNET_MSG_GET); > - BUILD_BUG_ON(LNET_REPLY_BIT != 1 << LNET_MSG_REPLY); Why does this not have any value? How are you ensuring that these requirements are now being met? thanks, greg k-h From andreas.dilger at intel.com Fri Mar 24 20:10:16 2017 From: andreas.dilger at intel.com (Dilger, Andreas) Date: Fri, 24 Mar 2017 20:10:16 +0000 Subject: [lustre-devel] [PATCH] staging: lustre: Remove redundant code In-Reply-To: <20170324134459.GA26275@kroah.com> References: <20170324113952.GA31427@arushi-HP-Pavilion-Notebook> <20170324134459.GA26275@kroah.com> Message-ID: <9D55D2DC-3CEB-471E-B37F-1721D1B328DA@intel.com> On Mar 24, 2017, at 07:44, Greg Kroah-Hartman wrote: > > On Fri, Mar 24, 2017 at 05:09:53PM +0530, Arushi Singhal wrote: >> Remove the code which do not have any value. >> >> Signed-off-by: Arushi Singhal >> --- >> drivers/staging/lustre/lnet/lnet/net_fault.c | 5 ----- >> 1 file changed, 5 deletions(-) >> >> diff --git a/drivers/staging/lustre/lnet/lnet/net_fault.c b/drivers/staging/lustre/lnet/lnet/net_fault.c >> index 18183cbb9859..b60261db9e67 100644 >> --- a/drivers/staging/lustre/lnet/lnet/net_fault.c >> +++ b/drivers/staging/lustre/lnet/lnet/net_fault.c >> @@ -997,11 +997,6 @@ lnet_fault_ctl(int opc, struct libcfs_ioctl_data *data) >> int >> lnet_fault_init(void) >> { >> - BUILD_BUG_ON(LNET_PUT_BIT != 1 << LNET_MSG_PUT); >> - BUILD_BUG_ON(LNET_ACK_BIT != 1 << LNET_MSG_ACK); >> - BUILD_BUG_ON(LNET_GET_BIT != 1 << LNET_MSG_GET); >> - BUILD_BUG_ON(LNET_REPLY_BIT != 1 << LNET_MSG_REPLY); > > Why does this not have any value? How are you ensuring that these > requirements are now being met? It was my recommendation to remove these checks, though on closer review I might have been a bit premature. For some reason I thought the LNET_*_BIT constants were defined in terms of LNET_MSG_*, but I see they are not. In conjunction with this change, the definition of LNET_*_BIT should be changed to be defined in terms of the LNET_MSG_* constants: #define LNET_PUT_BIT BIT(LNET_MSG_PUT) #define LNET_ACK_BIT BIT(LNET_MSG_ACK) #define LNET_GET_BIT BIT(LNET_MSG_GET) #define LNET_REPLY_BIT BIT(LNET_MSG_REPLY) The alternative would be to remove the LNET_*_BIT constants and use BIT(LNET_MSG_*) directly in the code, since that is easy enough to read compared to (1 << LNET_MSG_*) everywhere. There don't seem to be a lot of users, so this wouldn't be a giant patch. Cheers, Andreas -- Andreas Dilger Lustre Principal Architect Intel Corporation From andreas.dilger at intel.com Fri Mar 24 22:22:06 2017 From: andreas.dilger at intel.com (Dilger, Andreas) Date: Fri, 24 Mar 2017 22:22:06 +0000 Subject: [lustre-devel] [PATCH 1/6] Autoconf option for rate-limiting Quality of Service (RLQOS) In-Reply-To: <99fe8fdaaaa5b6fd36c0782269bc45a580079696.1490122510.git.yanli@ascar.io> References: <99fe8fdaaaa5b6fd36c0782269bc45a580079696.1490122510.git.yanli@ascar.io> Message-ID: <3FFFCE73-97FE-4A10-8AC6-47D835CC6B3C@intel.com> On Mar 21, 2017, at 13:43, Yan Li wrote: > > This patch enables rate-limiting quality of service (RLQOS) support as > talked in the ASCAR paper [1]. The purpose of RLQOS is to provide a > client-side rate limiting mechanism that controls max_rpcs_in_flight > and minimal gap between brw RPC requests (called tau in the code and > paper). > > RLQOS can be enabled by passing --enable-rlqos to configure. It then > can be controlled by tunables in procfs of each osc. Hi Yan, thanks for submitting the patch series. Two high level comments on the patches, since I haven't had a chance to review them in detail (though I see Alexey has commented on some of them): - What external tools (if any) are needed in order to use this functionality? Are these available for download, and is there documentation for using them? - It is fine that you've submitted the patches here for discussion and to raise awareness of your work. In order to get them landed you should submit the patches to Gerrit (see https://wiki.hpdd.intel.com/display/PUB/Using+Gerrit I'll try to take a look at them when I get a chance. This may also be of interest to Li Xi and Qian at DDN, who have been working on server-side NRS. Cheers, Andreas > [1] http://storageconference.us/2015/Papers/14.Li.pdf > > Signed-off-by: Yan Li > --- > lustre/autoconf/lustre-core.m4 | 17 +++++++++++++++++ > lustre/include/Makefile.am | 3 ++- > 2 files changed, 19 insertions(+), 1 deletion(-) > > diff --git a/lustre/autoconf/lustre-core.m4 b/lustre/autoconf/lustre-core.m4 > index 0578325..7f1828e 100644 > --- a/lustre/autoconf/lustre-core.m4 > +++ b/lustre/autoconf/lustre-core.m4 > @@ -369,6 +369,22 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([ > AC_MSG_RESULT([$enable_ssk]) > ]) # LC_OPENSSL_SSK > > +# > +# LC_CONFIG_RLQOS > +# > +# Rate-limiting Quality of Service support > +# > +AC_DEFUN([LC_CONFIG_RLQOS], [ > +AC_MSG_CHECKING([whether to enable rate-limiting quality of service support]) > +AC_ARG_ENABLE([rlqos], > + AC_HELP_STRING([--enable-rlqos], > + [enable rate-limiting quality of service support]), > + [], [enable_rlqos="no"]) > +AC_MSG_RESULT([$enable_rlqos]) > +AS_IF([test "x$enable_rlqos" != xno], > + [AC_DEFINE(ENABLE_RLQOS, 1, [enable rate-limiting quality of service support])]) > +]) # LC_CONFIG_RLQOS > + > # LC_INODE_PERMISION_2ARGS > # > # up to v2.6.27 had a 3 arg version (inode, mask, nameidata) > @@ -2241,6 +2257,7 @@ AC_DEFUN([LC_PROG_LINUX], [ > LC_GLIBC_SUPPORT_FHANDLES > LC_CONFIG_GSS > LC_OPENSSL_SSK > + LC_CONFIG_RLQOS > > # 2.6.32 > LC_BLK_QUEUE_MAX_SEGMENTS > diff --git a/lustre/include/Makefile.am b/lustre/include/Makefile.am > index 9074ca4..6d72b6e 100644 > --- a/lustre/include/Makefile.am > +++ b/lustre/include/Makefile.am > @@ -98,4 +98,5 @@ EXTRA_DIST = \ > upcall_cache.h \ > lustre_kernelcomm.h \ > seq_range.h \ > - uapi_kernelcomm.h > + uapi_kernelcomm.h \ > + rlqos.h > -- > 1.8.3.1 > > _______________________________________________ > lustre-devel mailing list > lustre-devel at lists.lustre.org > http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org Cheers, Andreas -- Andreas Dilger Lustre Principal Architect Intel Corporation From adilger at dilger.ca Mon Mar 27 01:12:28 2017 From: adilger at dilger.ca (Andreas Dilger) Date: Sun, 26 Mar 2017 19:12:28 -0600 Subject: [lustre-devel] [RFC] Proposal to add a new mount option 'norootwrite' In-Reply-To: References: Message-ID: <6682A67D-F0FB-4B0A-9D05-64AA4DC6686F@dilger.ca> [Limit discussion to lustre-devel, since this is Lustre-specific] On Mar 23, 2017, at 5:25 PM, Jay Lan wrote: > NASA Ames manages a large collection of tightly integrated Linux based systems. 100's of server nodes for Lustre, 10's of NFS servers, and >10,000 compute nodes and 10's of other role specifics systems, many of which mount several different network based filesystems. Some of these filesystems are far too large to effectively backup (e.g. >20PB), because of cost or data turnover rates. Being Linux, there are many interrelated scripts and configuration management tools running with root level privileges on all of the systems. > > There are significant risks associated with user data loss caused by unintended root write privilege. Some of these scenarios include: > 1) admin typing incorrect command, or in the wrong window > 2) errant root script > 3) system configuration management tools (e.g. bcfg2), running in ways or on systems that remove data as part of configuration management. > > Over the years, we have been bitten by all of these. A recent event with bcfg2 has motivated us to develop a mechanism to protect against this class of problems. Specifically, against root removing user data on network mounted filesystems. > > After discussing internally, we find that there are a large number of our systems where root should not be able to unlink remotely mounted files, but root does need to be able to scan directories and read files. Root squash to nobody does not meet the needs we have in managing systems, which includes administrators debugging complex large scale problems across multiple systems. > > We developed prototype code in the VFS layer that effectively prevents root from writing or updating directories or files on network mounted filesystems, as a mount option, called norootwrite. This can then be individually configured for each filesystem we want to protect. This has been developed/tested on NFS, Lustre and a locally mounted ext3 filesystem. > > Some consideration was also given to potentially limit a client mount privileged by developing an /etc/exports like permission to prevent certain hosts or ip ranges from mounting without norootwrite, but this quickly ramped up the implementation complexity, so we rejected that. > This is considered a weakness. Specifically, a remote system could unintentionally mount without norootwrite and then remove user data. I think a complete implementation should include this. Note that this sounds like something that could be implemented fairly easily in the Lustre "nodemap" infrastructure that IU developed for UID/GID mapping and landed in the Lustre 2.9 release. Nodemap is useful for other server-side enforcement mechanisms, such as root squash, and I suspect it wouldn't be hard to add in a check to only disallow unlink by root users. That would avoid the need to even mount clients with "-o norootwrite" at all - it would be a policy implemented on the MDS by the admin, regardless of whether the client machine was configured this way or not. It would still be possible to whitelist some client machines to allow root unlinking of files if needed. Cheers, Andreas > Features of Norootwrite in our prototype are > 1. You need to enable norootwrite option for it to work. 'Rootwrite' is the default. > > 2. With 'norootwrite' enabled, root is treated like a normal user on write permission. > > 3. The norootwrite option can be added to /etc/fstab entries. > > 4. It can also be enabled/disabled on the fly via 'mount -o remount' specifying norootwrite or rootwrite. > > In addition to a kernel patch, mount commands need to be taught to understand this new mount option: /bin/mount, /sbin/mount.nfs, and /sbin/mount.lustre. > > The prototype was developed in SLES11 SP4. I am working on a version for SLES12 SP2 for more testing. Obviously, we don't want to carry these patches indefinitely and are looking for guidance from the community on whether something like this could land mainline or be changed in some way to be more acceptable than the current form. > > Comments are very appreciated. A kernel patch against the latest upstream kernel release will be posted here after we concluded testing. > Cheers, Andreas -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 195 bytes Desc: Message signed with OpenPGP URL: From aprout at ll.mit.edu Mon Mar 27 16:37:42 2017 From: aprout at ll.mit.edu (Prout, Andrew - LLSC - MITLL) Date: Mon, 27 Mar 2017 16:37:42 +0000 Subject: [lustre-devel] [RFC] Proposal to add a new mount option 'norootwrite' In-Reply-To: <6682A67D-F0FB-4B0A-9D05-64AA4DC6686F@dilger.ca> References: <6682A67D-F0FB-4B0A-9D05-64AA4DC6686F@dilger.ca> Message-ID: Is the proposal essentially equivalent to dropping CAP_DAC_OVERRIDE (while keeping CAP_DAC_READ_SEARCH) on filesystems mounted with this option? Would root still have the ability to perform the actions covered by CAP_CHOWN, CAP_FOWNER, CAP_SETFCAP, or CAP_FSETID? Andrew Prout Lincoln Laboratory Supercomputing Center MIT Lincoln Laboratory 244 Wood Street, Lexington, MA 02421 -----Original Message----- From: lustre-devel [mailto:lustre-devel-bounces at lists.lustre.org] On Behalf Of Andreas Dilger Sent: Sunday, March 26, 2017 9:12 PM To: Jay Lan Cc: lustre-devel at lists.lustre.org List Subject: Re: [lustre-devel] [RFC] Proposal to add a new mount option 'norootwrite' [Limit discussion to lustre-devel, since this is Lustre-specific] On Mar 23, 2017, at 5:25 PM, Jay Lan wrote: > NASA Ames manages a large collection of tightly integrated Linux based systems. 100's of server nodes for Lustre, 10's of NFS servers, and >10,000 compute nodes and 10's of other role specifics systems, many of which mount several different network based filesystems. Some of these filesystems are far too large to effectively backup (e.g. >20PB), because of cost or data turnover rates. Being Linux, there are many interrelated scripts and configuration management tools running with root level privileges on all of the systems. > > There are significant risks associated with user data loss caused by unintended root write privilege. Some of these scenarios include: > 1) admin typing incorrect command, or in the wrong window > 2) errant root script > 3) system configuration management tools (e.g. bcfg2), running in ways or on systems that remove data as part of configuration management. > > Over the years, we have been bitten by all of these. A recent event with bcfg2 has motivated us to develop a mechanism to protect against this class of problems. Specifically, against root removing user data on network mounted filesystems. > > After discussing internally, we find that there are a large number of our systems where root should not be able to unlink remotely mounted files, but root does need to be able to scan directories and read files. Root squash to nobody does not meet the needs we have in managing systems, which includes administrators debugging complex large scale problems across multiple systems. > > We developed prototype code in the VFS layer that effectively prevents root from writing or updating directories or files on network mounted filesystems, as a mount option, called norootwrite. This can then be individually configured for each filesystem we want to protect. This has been developed/tested on NFS, Lustre and a locally mounted ext3 filesystem. > > Some consideration was also given to potentially limit a client mount privileged by developing an /etc/exports like permission to prevent certain hosts or ip ranges from mounting without norootwrite, but this quickly ramped up the implementation complexity, so we rejected that. > This is considered a weakness. Specifically, a remote system could unintentionally mount without norootwrite and then remove user data. I think a complete implementation should include this. Note that this sounds like something that could be implemented fairly easily in the Lustre "nodemap" infrastructure that IU developed for UID/GID mapping and landed in the Lustre 2.9 release. Nodemap is useful for other server-side enforcement mechanisms, such as root squash, and I suspect it wouldn't be hard to add in a check to only disallow unlink by root users. That would avoid the need to even mount clients with "-o norootwrite" at all - it would be a policy implemented on the MDS by the admin, regardless of whether the client machine was configured this way or not. It would still be possible to whitelist some client machines to allow root unlinking of files if needed. Cheers, Andreas > Features of Norootwrite in our prototype are > 1. You need to enable norootwrite option for it to work. 'Rootwrite' is the default. > > 2. With 'norootwrite' enabled, root is treated like a normal user on write permission. > > 3. The norootwrite option can be added to /etc/fstab entries. > > 4. It can also be enabled/disabled on the fly via 'mount -o remount' specifying norootwrite or rootwrite. > > In addition to a kernel patch, mount commands need to be taught to understand this new mount option: /bin/mount, /sbin/mount.nfs, and /sbin/mount.lustre. > > The prototype was developed in SLES11 SP4. I am working on a version for SLES12 SP2 for more testing. Obviously, we don't want to carry these patches indefinitely and are looking for guidance from the community on whether something like this could land mainline or be changed in some way to be more acceptable than the current form. > > Comments are very appreciated. A kernel patch against the latest upstream kernel release will be posted here after we concluded testing. > Cheers, Andreas From oleg.drokin at intel.com Wed Mar 29 03:24:14 2017 From: oleg.drokin at intel.com (Oleg Drokin) Date: Tue, 28 Mar 2017 23:24:14 -0400 Subject: [lustre-devel] [PATCH 1/1] Staging: lustre: lnet: libcfs: Fixed checkpatch.pl coding style errors In-Reply-To: <1490695812-20475-1-git-send-email-vaibhavddit@gmail.com> References: <1490695812-20475-1-git-send-email-vaibhavddit@gmail.com> Message-ID: <5E15E74D-877E-4551-B9C2-57DDC77A8E26@intel.com> On Mar 28, 2017, at 6:10 AM, wrote: > From: Vaibhav Kothari > > Shifted open brace { to previous line for 8 functions as indicated by > checkpatch.pl > > Signed-off-by: Vaibhav Kothari > --- > drivers/staging/lustre/lnet/libcfs/hash.c | 43 +++++++++++-------------------- > 1 file changed, 15 insertions(+), 28 deletions(-) > > diff --git a/drivers/staging/lustre/lnet/libcfs/hash.c b/drivers/staging/lustre/lnet/libcfs/hash.c > index 5c2ce2e..bb966e2 100644 > --- a/drivers/staging/lustre/lnet/libcfs/hash.c > +++ b/drivers/staging/lustre/lnet/libcfs/hash.c > @@ -1348,8 +1348,7 @@ void cfs_hash_putref(struct cfs_hash *hs) > EXPORT_SYMBOL(cfs_hash_lookup); > > static void > -cfs_hash_for_each_enter(struct cfs_hash *hs) > -{ > +cfs_hash_for_each_enter(struct cfs_hash *hs) { Ugh, no. This is obviously a false positive in checkpatch. > LASSERT(!cfs_hash_is_exiting(hs)); > > if (!cfs_hash_with_rehash(hs)) > @@ -1375,8 +1374,7 @@ void cfs_hash_putref(struct cfs_hash *hs) > } > > static void > -cfs_hash_for_each_exit(struct cfs_hash *hs) > -{ > +cfs_hash_for_each_exit(struct cfs_hash *hs) { > int remained; > int bits; > > @@ -1407,8 +1405,7 @@ void cfs_hash_putref(struct cfs_hash *hs) > */ > static u64 > cfs_hash_for_each_tight(struct cfs_hash *hs, cfs_hash_for_each_cb_t func, > - void *data, int remove_safe) > -{ > + void *data, int remove_safe) { > struct hlist_node *hnode; > struct hlist_node *pos; > struct cfs_hash_bd bd; > @@ -1465,8 +1462,7 @@ struct cfs_hash_cond_arg { > > static int > cfs_hash_cond_del_locked(struct cfs_hash *hs, struct cfs_hash_bd *bd, > - struct hlist_node *hnode, void *data) > -{ > + struct hlist_node *hnode, void *data) { > struct cfs_hash_cond_arg *cond = data; > > if (cond->func(cfs_hash_object(hs, hnode), cond->arg)) > @@ -1480,8 +1476,8 @@ struct cfs_hash_cond_arg { > * any object be reference. > */ > void > -cfs_hash_cond_del(struct cfs_hash *hs, cfs_hash_cond_opt_cb_t func, void *data) > -{ > +cfs_hash_cond_del(struct cfs_hash *hs, cfs_hash_cond_opt_cb_t func, > + void *data) { > struct cfs_hash_cond_arg arg = { > .func = func, > .arg = data, > @@ -1493,31 +1489,27 @@ struct cfs_hash_cond_arg { > > void > cfs_hash_for_each(struct cfs_hash *hs, cfs_hash_for_each_cb_t func, > - void *data) > -{ > + void *data) { > cfs_hash_for_each_tight(hs, func, data, 0); > } > EXPORT_SYMBOL(cfs_hash_for_each); > > void > cfs_hash_for_each_safe(struct cfs_hash *hs, cfs_hash_for_each_cb_t func, > - void *data) > -{ > + void *data) { > cfs_hash_for_each_tight(hs, func, data, 1); > } > EXPORT_SYMBOL(cfs_hash_for_each_safe); > > static int > cfs_hash_peek(struct cfs_hash *hs, struct cfs_hash_bd *bd, > - struct hlist_node *hnode, void *data) > -{ > + struct hlist_node *hnode, void *data) { > *(int *)data = 0; > return 1; /* return 1 to break the loop */ > } > > int > -cfs_hash_is_empty(struct cfs_hash *hs) > -{ > +cfs_hash_is_empty(struct cfs_hash *hs) { > int empty = 1; > > cfs_hash_for_each_tight(hs, cfs_hash_peek, &empty, 0); > @@ -1526,8 +1518,7 @@ struct cfs_hash_cond_arg { > EXPORT_SYMBOL(cfs_hash_is_empty); > > u64 > -cfs_hash_size_get(struct cfs_hash *hs) > -{ > +cfs_hash_size_get(struct cfs_hash *hs) { > return cfs_hash_with_counter(hs) ? > atomic_read(&hs->hs_count) : > cfs_hash_for_each_tight(hs, NULL, NULL, 0); > @@ -1551,8 +1542,7 @@ struct cfs_hash_cond_arg { > */ > static int > cfs_hash_for_each_relax(struct cfs_hash *hs, cfs_hash_for_each_cb_t func, > - void *data, int start) > -{ > + void *data, int start) { > struct hlist_node *hnode; > struct hlist_node *tmp; > struct cfs_hash_bd bd; > @@ -1629,8 +1619,7 @@ struct cfs_hash_cond_arg { > > int > cfs_hash_for_each_nolock(struct cfs_hash *hs, cfs_hash_for_each_cb_t func, > - void *data, int start) > -{ > + void *data, int start) { > if (cfs_hash_with_no_lock(hs) || > cfs_hash_with_rehash_key(hs) || > !cfs_hash_with_no_itemref(hs)) > @@ -1661,8 +1650,7 @@ struct cfs_hash_cond_arg { > */ > int > cfs_hash_for_each_empty(struct cfs_hash *hs, cfs_hash_for_each_cb_t func, > - void *data) > -{ > + void *data) { > unsigned int i = 0; > > if (cfs_hash_with_no_lock(hs)) > @@ -1718,8 +1706,7 @@ struct cfs_hash_cond_arg { > */ > void > cfs_hash_for_each_key(struct cfs_hash *hs, const void *key, > - cfs_hash_for_each_cb_t func, void *data) > -{ > + cfs_hash_for_each_cb_t func, void *data) { > struct hlist_node *hnode; > struct cfs_hash_bd bds[2]; > unsigned int i; > -- > 1.9.1 From andreas.dilger at intel.com Wed Mar 29 05:05:07 2017 From: andreas.dilger at intel.com (Dilger, Andreas) Date: Wed, 29 Mar 2017 05:05:07 +0000 Subject: [lustre-devel] [PATCH] Remove sparse warnings in mdc_request.c In-Reply-To: <58d9f73a.09c3620a.d471b.d171@mx.google.com> References: <58d9f73a.09c3620a.d471b.d171@mx.google.com> Message-ID: <1592C3AC-DE8B-4A11-8053-02B82A61E1B3@intel.com> On Mar 27, 2017, at 23:40, Skanda Guruanand wrote: > > I have tried to fix the endian issues in the mdc_request.c in the > lustre file system drivers in the staging area. Your feedback is > welcome. Sorry, but this patch is totally wrong. This would break the handling of this structure on big-endian systems. The right fix would be to change the declaration of ldp_hash_start and ldp_hash_end from __u64 to __le64, along with ldp_flags and ldp_pad0 (though it should be unused). Cheers, Andreas > CHECK drivers/staging/lustre/lustre/mdc/mdc_request.c > drivers/staging/lustre/lustre/mdc/mdc_request.c:958:42: warning: cast > to restricted __le64 > drivers/staging/lustre/lustre/mdc/mdc_request.c:959:42: warning: cast > to restricted __le64 > drivers/staging/lustre/lustre/mdc/mdc_request.c:962:42: warning: cast > to restricted __le64 > drivers/staging/lustre/lustre/mdc/mdc_request.c:963:42: warning: cast > to restricted __le64 > drivers/staging/lustre/lustre/mdc/mdc_request.c:985:50: warning: cast > to restricted __le32 > drivers/staging/lustre/lustre/mdc/mdc_request.c:1193:24: warning: cast > to restricted __le64 > drivers/staging/lustre/lustre/mdc/mdc_request.c:1328:25: warning: cast > to restricted __le64 > drivers/staging/lustre/lustre/mdc/mdc_request.c:1329:23: warning: cast > to restricted __le64 > drivers/staging/lustre/lustre/mdc/mdc_request.c:1332:25: warning: cast > to restricted __le64 > drivers/staging/lustre/lustre/mdc/mdc_request.c:1333:23: warning: cast > to restricted __le64 > > --- > drivers/staging/lustre/lustre/mdc/mdc_request.c | 20 ++++++++++---------- > 1 file changed, 10 insertions(+), 10 deletions(-) > > diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c > index 6bc2fb8..aa8837c 100644 > --- a/drivers/staging/lustre/lustre/mdc/mdc_request.c > +++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c > @@ -955,12 +955,12 @@ static struct page *mdc_page_locate(struct address_space *mapping, __u64 *hash, > if (PageUptodate(page)) { > dp = kmap(page); > if (BITS_PER_LONG == 32 && hash64) { > - *start = le64_to_cpu(dp->ldp_hash_start) >> 32; > - *end = le64_to_cpu(dp->ldp_hash_end) >> 32; > + *start = dp->ldp_hash_start >> 32; > + *end = dp->ldp_hash_end >> 32; > *hash = *hash >> 32; > } else { > - *start = le64_to_cpu(dp->ldp_hash_start); > - *end = le64_to_cpu(dp->ldp_hash_end); > + *start = dp->ldp_hash_start; > + *end = dp->ldp_hash_end; > } > if (unlikely(*start == 1 && *hash == 0)) > *hash = *start; > @@ -982,7 +982,7 @@ static struct page *mdc_page_locate(struct address_space *mapping, __u64 *hash, > */ > kunmap(page); > mdc_release_page(page, > - le32_to_cpu(dp->ldp_flags) & LDF_COLLIDE); > + dp->ldp_flags & LDF_COLLIDE); Note that it would also be acceptable to use "cpu_to_le32(LDF_COLLIDE)" here, since swabbing a constant is a compile-time operation, while swabbing a variable adds runtime overhead on big-endian systems. > page = NULL; > } > } else { > @@ -1190,7 +1190,7 @@ static int mdc_read_page_remote(void *data, struct page *page0) > SetPageUptodate(page); > > dp = kmap(page); > - hash = le64_to_cpu(dp->ldp_hash_start); > + hash = dp->ldp_hash_start; > kunmap(page); > > offset = hash_x_index(hash, rp->rp_hash64); > @@ -1325,12 +1325,12 @@ static int mdc_read_page(struct obd_export *exp, struct md_op_data *op_data, > hash_collision: > dp = page_address(page); > if (BITS_PER_LONG == 32 && rp_param.rp_hash64) { > - start = le64_to_cpu(dp->ldp_hash_start) >> 32; > - end = le64_to_cpu(dp->ldp_hash_end) >> 32; > + start = dp->ldp_hash_start >> 32; > + end = dp->ldp_hash_end >> 32; > rp_param.rp_off = hash_offset >> 32; > } else { > - start = le64_to_cpu(dp->ldp_hash_start); > - end = le64_to_cpu(dp->ldp_hash_end); > + start = dp->ldp_hash_start; > + end = dp->ldp_hash_end; > rp_param.rp_off = hash_offset; > } > if (end == start) { > -- > 1.9.1 > Cheers, Andreas -- Andreas Dilger Lustre Principal Architect Intel Corporation From gregkh at linuxfoundation.org Wed Mar 29 07:31:14 2017 From: gregkh at linuxfoundation.org (Greg KH) Date: Wed, 29 Mar 2017 09:31:14 +0200 Subject: [lustre-devel] [PATCH] staging: lusten: conrpc.c: fix different address space sparse warning In-Reply-To: <20170329021409.24537-1-marcos.souza.org@gmail.com> References: <20170329021409.24537-1-marcos.souza.org@gmail.com> Message-ID: <20170329073114.GA8459@kroah.com> On Tue, Mar 28, 2017 at 11:14:06PM -0300, Marcos Paulo de Souza wrote: > head_up parameter is marked with __user attribute, tmp is filled > by a copy_from_user from next, that is also marked as __user, so > tmp.next needs to be "casted" as __user to make sparse happy. But is it the correct change? You also have a typo in your subject :( > Signed-off-by: Marcos Paulo de Souza > --- > > this is mt first patch addressing an issue of sparse, so let me know > if I misunderstood the error message > > drivers/staging/lustre/lnet/selftest/conrpc.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/staging/lustre/lnet/selftest/conrpc.c b/drivers/staging/lustre/lnet/selftest/conrpc.c > index c6a683b..fb7ad74 100644 > --- a/drivers/staging/lustre/lnet/selftest/conrpc.c > +++ b/drivers/staging/lustre/lnet/selftest/conrpc.c > @@ -487,7 +487,7 @@ lstcon_rpc_trans_interpreter(struct lstcon_rpc_trans *trans, > sizeof(struct list_head))) > return -EFAULT; > > - if (tmp.next == head_up) > + if ((struct list_head __user *)tmp.next == head_up) Aer you sure this is correct? __user changes for lustre is not trivial... How did you test this? thanks, greg k-h From greg at kroah.com Wed Mar 29 07:33:20 2017 From: greg at kroah.com (Greg KH) Date: Wed, 29 Mar 2017 09:33:20 +0200 Subject: [lustre-devel] [PATCH] Clear sparse warning: different address space In-Reply-To: <20170325030503.31675-1-kedrot@gmail.com> References: <20170325030503.31675-1-kedrot@gmail.com> Message-ID: <20170329073320.GD8459@kroah.com> On Sat, Mar 25, 2017 at 12:05:03AM -0300, Guillermo O. Freschi wrote: > Made tagged `index` as `__user` to remove warning from > `obd_iocontrol` call. Your subject line is odd, please make it match other changes for this driver. > Signed-off-by: Guillermo O. Freschi > --- > drivers/staging/lustre/lustre/llite/dir.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c > index 13b35922a4ca..acdde21d41d9 100644 > --- a/drivers/staging/lustre/lustre/llite/dir.c > +++ b/drivers/staging/lustre/lustre/llite/dir.c > @@ -1464,7 +1464,7 @@ static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg) > case LL_IOC_FID2MDTIDX: { > struct obd_export *exp = ll_i2mdexp(inode); > struct lu_fid fid; > - __u32 index; > + __u32 __user index; Are you sure? How did you test this? thanks, greg k-h From gregkh at linuxfoundation.org Wed Mar 29 10:34:05 2017 From: gregkh at linuxfoundation.org (Greg KH) Date: Wed, 29 Mar 2017 12:34:05 +0200 Subject: [lustre-devel] [PATCH] staging: lusten: conrpc.c: fix different address space sparse warning In-Reply-To: <20170323190901.GA22066@builder> References: <20170329021409.24537-1-marcos.souza.org@gmail.com> <20170329073114.GA8459@kroah.com> <20170323190901.GA22066@builder> Message-ID: <20170329103405.GA4087@kroah.com> On Thu, Mar 23, 2017 at 04:09:03PM -0300, Marcos Paulo de Souza wrote: > On Wed, Mar 29, 2017 at 09:31:14AM +0200, Greg KH wrote: > > On Tue, Mar 28, 2017 at 11:14:06PM -0300, Marcos Paulo de Souza wrote: > > > head_up parameter is marked with __user attribute, tmp is filled > > > by a copy_from_user from next, that is also marked as __user, so > > > tmp.next needs to be "casted" as __user to make sparse happy. > > > > But is it the correct change? > > I don't know, it's my first sparse patch, so I tried to fix this > warning. > > > > > You also have a typo in your subject :( > > Sorry, didn't noticed yesterday :( > > > > > > Signed-off-by: Marcos Paulo de Souza > > > --- > > > > > > this is mt first patch addressing an issue of sparse, so let me know > > > if I misunderstood the error message > > > > > > drivers/staging/lustre/lnet/selftest/conrpc.c | 2 +- > > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > > > diff --git a/drivers/staging/lustre/lnet/selftest/conrpc.c b/drivers/staging/lustre/lnet/selftest/conrpc.c > > > index c6a683b..fb7ad74 100644 > > > --- a/drivers/staging/lustre/lnet/selftest/conrpc.c > > > +++ b/drivers/staging/lustre/lnet/selftest/conrpc.c > > > @@ -487,7 +487,7 @@ lstcon_rpc_trans_interpreter(struct lstcon_rpc_trans *trans, > > > sizeof(struct list_head))) > > > return -EFAULT; > > > > > > - if (tmp.next == head_up) > > > + if ((struct list_head __user *)tmp.next == head_up) > > > > Aer you sure this is correct? __user changes for lustre is not > > trivial... > > > > How did you test this? > > I didn't tested, it just removed the warning. Is this a false positive? I don't know, it's up to you to prove to me that you know this change is correct. You have to justify your changes, and "because checkpatch.pl complained" isn't a valid justification for something like this :) thanks, greg k-h From jack at suse.cz Wed Mar 29 10:55:58 2017 From: jack at suse.cz (Jan Kara) Date: Wed, 29 Mar 2017 12:55:58 +0200 Subject: [lustre-devel] [PATCH 0/25 v2] fs: Convert all embedded bdis into separate ones Message-ID: <20170329105623.18241-1-jack@suse.cz> Hello, this is the second revision of the patch series which converts all embedded occurences of struct backing_dev_info to use standalone dynamically allocated structures. This makes bdi handling unified across all bdi users and generally removes some boilerplate code from filesystems setting up their own bdi. It also allows us to remove some code from generic bdi implementation. The patches were only compile-tested for most filesystems (I've tested mounting only for NFS & btrfs) so fs maintainers please have a look whether the changes look sound to you. This series is based on top of bdi fixes that were merged into linux-block git tree into for-next branch. I have pushed out the result as a branch to git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs.git bdi Changes since v1: * Added some acks * Added further FUSE cleanup patch * Added removal of unused argument to bdi_register() * Fixed up some compilation failures spotted by 0-day testing Honza From jack at suse.cz Wed Mar 29 10:56:02 2017 From: jack at suse.cz (Jan Kara) Date: Wed, 29 Mar 2017 12:56:02 +0200 Subject: [lustre-devel] [PATCH 04/25] fs: Provide infrastructure for dynamic BDIs in filesystems In-Reply-To: <20170329105623.18241-1-jack@suse.cz> References: <20170329105623.18241-1-jack@suse.cz> Message-ID: <20170329105623.18241-5-jack@suse.cz> Provide helper functions for setting up dynamically allocated backing_dev_info structures for filesystems and cleaning them up on superblock destruction. CC: linux-mtd at lists.infradead.org CC: linux-nfs at vger.kernel.org CC: Petr Vandrovec CC: linux-nilfs at vger.kernel.org CC: cluster-devel at redhat.com CC: osd-dev at open-osd.org CC: codalist at coda.cs.cmu.edu CC: linux-afs at lists.infradead.org CC: ecryptfs at vger.kernel.org CC: linux-cifs at vger.kernel.org CC: ceph-devel at vger.kernel.org CC: linux-btrfs at vger.kernel.org CC: v9fs-developer at lists.sourceforge.net CC: lustre-devel at lists.lustre.org Signed-off-by: Jan Kara --- fs/super.c | 49 ++++++++++++++++++++++++++++++++++++++++ include/linux/backing-dev-defs.h | 2 +- include/linux/fs.h | 6 +++++ 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/fs/super.c b/fs/super.c index b8b6a086c03b..0f51a437c269 100644 --- a/fs/super.c +++ b/fs/super.c @@ -446,6 +446,11 @@ void generic_shutdown_super(struct super_block *sb) hlist_del_init(&sb->s_instances); spin_unlock(&sb_lock); up_write(&sb->s_umount); + if (sb->s_iflags & SB_I_DYNBDI) { + bdi_put(sb->s_bdi); + sb->s_bdi = &noop_backing_dev_info; + sb->s_iflags &= ~SB_I_DYNBDI; + } } EXPORT_SYMBOL(generic_shutdown_super); @@ -1256,6 +1261,50 @@ mount_fs(struct file_system_type *type, int flags, const char *name, void *data) } /* + * Setup private BDI for given superblock. It gets automatically cleaned up + * in generic_shutdown_super(). + */ +int super_setup_bdi_name(struct super_block *sb, char *fmt, ...) +{ + struct backing_dev_info *bdi; + int err; + va_list args; + + bdi = bdi_alloc(GFP_KERNEL); + if (!bdi) + return -ENOMEM; + + bdi->name = sb->s_type->name; + + va_start(args, fmt); + err = bdi_register_va(bdi, NULL, fmt, args); + va_end(args); + if (err) { + bdi_put(bdi); + return err; + } + WARN_ON(sb->s_bdi != &noop_backing_dev_info); + sb->s_bdi = bdi; + sb->s_iflags |= SB_I_DYNBDI; + + return 0; +} +EXPORT_SYMBOL(super_setup_bdi_name); + +/* + * Setup private BDI for given superblock. I gets automatically cleaned up + * in generic_shutdown_super(). + */ +int super_setup_bdi(struct super_block *sb) +{ + static atomic_long_t bdi_seq = ATOMIC_LONG_INIT(0); + + return super_setup_bdi_name(sb, "%.28s-%ld", sb->s_type->name, + atomic_long_inc_return(&bdi_seq)); +} +EXPORT_SYMBOL(super_setup_bdi); + +/* * This is an internal function, please use sb_end_{write,pagefault,intwrite} * instead. */ diff --git a/include/linux/backing-dev-defs.h b/include/linux/backing-dev-defs.h index e66d4722db8e..866c433e7d32 100644 --- a/include/linux/backing-dev-defs.h +++ b/include/linux/backing-dev-defs.h @@ -146,7 +146,7 @@ struct backing_dev_info { congested_fn *congested_fn; /* Function pointer if device is md/dm */ void *congested_data; /* Pointer to aux data for congested func */ - char *name; + const char *name; struct kref refcnt; /* Reference counter for the structure */ unsigned int capabilities; /* Device capabilities */ diff --git a/include/linux/fs.h b/include/linux/fs.h index 7251f7bb45e8..98cf14ea78c0 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1272,6 +1272,9 @@ struct mm_struct; /* sb->s_iflags to limit user namespace mounts */ #define SB_I_USERNS_VISIBLE 0x00000010 /* fstype already mounted */ +/* Temporary flag until all filesystems are converted to dynamic bdis */ +#define SB_I_DYNBDI 0x00000100 + /* Possible states of 'frozen' field */ enum { SB_UNFROZEN = 0, /* FS is unfrozen */ @@ -2121,6 +2124,9 @@ extern int vfs_ustat(dev_t, struct kstatfs *); extern int freeze_super(struct super_block *super); extern int thaw_super(struct super_block *super); extern bool our_mnt(struct vfsmount *mnt); +extern __printf(2, 3) +int super_setup_bdi_name(struct super_block *sb, char *fmt, ...); +extern int super_setup_bdi(struct super_block *sb); extern int current_umask(void); -- 2.10.2 From jack at suse.cz Wed Mar 29 10:56:04 2017 From: jack at suse.cz (Jan Kara) Date: Wed, 29 Mar 2017 12:56:04 +0200 Subject: [lustre-devel] [PATCH 06/25] lustre: Convert to separately allocated bdi In-Reply-To: <20170329105623.18241-1-jack@suse.cz> References: <20170329105623.18241-1-jack@suse.cz> Message-ID: <20170329105623.18241-7-jack@suse.cz> Allocate struct backing_dev_info separately instead of embedding it inside superblock. This unifies handling of bdi among users. CC: Oleg Drokin CC: Andreas Dilger CC: James Simmons CC: lustre-devel at lists.lustre.org Reviewed-by: Andreas Dilger Signed-off-by: Jan Kara --- .../staging/lustre/lustre/include/lustre_disk.h | 4 ---- drivers/staging/lustre/lustre/llite/llite_lib.c | 24 +++------------------- 2 files changed, 3 insertions(+), 25 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/lustre_disk.h b/drivers/staging/lustre/lustre/include/lustre_disk.h index 8886458748c1..a676bccabd43 100644 --- a/drivers/staging/lustre/lustre/include/lustre_disk.h +++ b/drivers/staging/lustre/lustre/include/lustre_disk.h @@ -133,13 +133,9 @@ struct lustre_sb_info { struct obd_export *lsi_osd_exp; char lsi_osd_type[16]; char lsi_fstype[16]; - struct backing_dev_info lsi_bdi; /* each client mountpoint needs - * own backing_dev_info - */ }; #define LSI_UMOUNT_FAILOVER 0x00200000 -#define LSI_BDI_INITIALIZED 0x00400000 #define s2lsi(sb) ((struct lustre_sb_info *)((sb)->s_fs_info)) #define s2lsi_nocast(sb) ((sb)->s_fs_info) diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index b229cbc7bb33..d483c44aafe5 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -863,15 +863,6 @@ void ll_lli_init(struct ll_inode_info *lli) mutex_init(&lli->lli_layout_mutex); } -static inline int ll_bdi_register(struct backing_dev_info *bdi) -{ - static atomic_t ll_bdi_num = ATOMIC_INIT(0); - - bdi->name = "lustre"; - return bdi_register(bdi, NULL, "lustre-%d", - atomic_inc_return(&ll_bdi_num)); -} - int ll_fill_super(struct super_block *sb, struct vfsmount *mnt) { struct lustre_profile *lprof = NULL; @@ -881,6 +872,7 @@ int ll_fill_super(struct super_block *sb, struct vfsmount *mnt) char *profilenm = get_profile_name(sb); struct config_llog_instance *cfg; int err; + static atomic_t ll_bdi_num = ATOMIC_INIT(0); CDEBUG(D_VFSTRACE, "VFS Op: sb %p\n", sb); @@ -903,16 +895,11 @@ int ll_fill_super(struct super_block *sb, struct vfsmount *mnt) if (err) goto out_free; - err = bdi_init(&lsi->lsi_bdi); - if (err) - goto out_free; - lsi->lsi_flags |= LSI_BDI_INITIALIZED; - lsi->lsi_bdi.capabilities = 0; - err = ll_bdi_register(&lsi->lsi_bdi); + err = super_setup_bdi_name(sb, "lustre-%d", + atomic_inc_return(&ll_bdi_num)); if (err) goto out_free; - sb->s_bdi = &lsi->lsi_bdi; /* kernel >= 2.6.38 store dentry operations in sb->s_d_op. */ sb->s_d_op = &ll_d_ops; @@ -1033,11 +1020,6 @@ void ll_put_super(struct super_block *sb) if (profilenm) class_del_profile(profilenm); - if (lsi->lsi_flags & LSI_BDI_INITIALIZED) { - bdi_destroy(&lsi->lsi_bdi); - lsi->lsi_flags &= ~LSI_BDI_INITIALIZED; - } - ll_free_sbi(sb); lsi->lsi_llsbi = NULL; -- 2.10.2 From gregkh at linuxfoundation.org Fri Mar 31 05:55:16 2017 From: gregkh at linuxfoundation.org (Greg KH) Date: Fri, 31 Mar 2017 07:55:16 +0200 Subject: [lustre-devel] [PATCH] Remove sparse warnings in mdc_request.c In-Reply-To: <1490936959-6337-2-git-send-email-skanda.kashyap@gmail.com> References: <1592C3AC-DE8B-4A11-8053-02B82A61E1B3@intel.com> <1490936959-6337-1-git-send-email-skanda.kashyap@gmail.com> <1490936959-6337-2-git-send-email-skanda.kashyap@gmail.com> Message-ID: <20170331055516.GA4811@kroah.com> On Thu, Mar 30, 2017 at 10:09:19PM -0700, skanda.kashyap at gmail.com wrote: > From: Skanda Guruanand > > --- > drivers/staging/lustre/lustre/include/lustre/lustre_idl.h | 8 ++++---- > 1 file changed, 4 insertions(+), 4 deletions(-) Hi, This is the friendly patch-bot of Greg Kroah-Hartman. You have sent him a patch that has triggered this response. He used to manually respond to these common problems, but in order to save his sanity (he kept writing the same thing over and over, yet to different people), I was created. Hopefully you will not take offence and will fix the problem in your patch and resubmit it so that it can be accepted into the Linux kernel tree. You are receiving this message because of the following common error(s) as indicated below: - Your patch does not have a Signed-off-by: line. Please read the kernel file, Documentation/SubmittingPatches and resend it after adding that line. Note, the line needs to be in the body of the email, before the patch, not at the bottom of the patch or in the email signature. - Your patch did many different things all at once, making it difficult to review. All Linux kernel patches need to only do one thing at a time. If you need to do multiple things (such as clean up all coding style issues in a file/driver), do it in a sequence of patches, each one doing only one thing. This will make it easier to review the patches to ensure that they are correct, and to help alleviate any merge issues that larger patches can cause. - You did not specify a description of why the patch is needed, or possibly, any description at all, in the email body. Please read the section entitled "The canonical patch format" in the kernel file, Documentation/SubmittingPatches for what is needed in order to properly describe the change. - You did not write a descriptive Subject: for the patch, allowing Greg, and everyone else, to know what this patch is all about. Please read the section entitled "The canonical patch format" in the kernel file, Documentation/SubmittingPatches for what a proper Subject: line should look like. If you wish to discuss this problem further, or you have questions about how to resolve this issue, please feel free to respond to this email and Greg will reply once he has dug out from the pending patches received from other developers. thanks, greg k-h's patch email bot