From patchwork Fri Jun 5 15:01:11 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Petr Mladek X-Patchwork-Id: 481366 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2001:1868:205::9]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 2099B1401DA for ; Sat, 6 Jun 2015 01:05:28 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Z0tA4-0002s9-4r; Fri, 05 Jun 2015 15:03:56 +0000 Received: from cantor2.suse.de ([195.135.220.15] helo=mx2.suse.de) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Z0t8i-00020C-EI for linux-mtd@lists.infradead.org; Fri, 05 Jun 2015 15:02:37 +0000 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id AF49EADDD; Fri, 5 Jun 2015 15:02:03 +0000 (UTC) From: Petr Mladek To: Andrew Morton , Oleg Nesterov , Tejun Heo , Ingo Molnar , Peter Zijlstra Subject: [RFC PATCH 12/18] lockd: Convert the central lockd service to kthread_iterant API Date: Fri, 5 Jun 2015 17:01:11 +0200 Message-Id: <1433516477-5153-13-git-send-email-pmladek@suse.cz> X-Mailer: git-send-email 1.8.5.6 In-Reply-To: <1433516477-5153-1-git-send-email-pmladek@suse.cz> References: <1433516477-5153-1-git-send-email-pmladek@suse.cz> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150605_080232_908089_60E16D8C X-CRM114-Status: GOOD ( 20.51 ) X-Spam-Score: -5.0 (-----) X-Spam-Report: SpamAssassin version 3.4.0 on bombadil.infradead.org summary: Content analysis details: (-5.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at http://www.dnswl.org/, high trust [195.135.220.15 listed in list.dnswl.org] Cc: linux-nfs@vger.kernel.org, Borislav Petkov , Jiri Kosina , Richard Weinberger , Trond Myklebust , linux-kernel@vger.kernel.org, Steven Rostedt , Michal Hocko , Chris Mason , Petr Mladek , linux-mtd@lists.infradead.org, linux-api@vger.kernel.org, Linus Torvalds , live-patching@vger.kernel.org, Thomas Gleixner , "Paul E. McKenney" , David Woodhouse , Anna Schumaker X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org The new iterant kthread API allows to define a common checkpoint for freezing, parking, termination, and even signal handling. It will allow to maintain kthreads more easily and make the operations more reliable. The kthread function is split into optional init(), func(), destroy() parts where func() is called in a cycle. The common check point is after each func() function finishes. See kthread_iterant_fn() for more details. This patch moves the action associated with the signal into a proper signal handler. It removes the obsolete set_freezable() call because iterant kthreads are freezable by default. struct kthread_iterant is stored into struct svc_rqst. We have already stored there the pointer to the related task_struct. The rest is just shuffling the code from the while cycle into _func(). Signed-off-by: Petr Mladek --- fs/lockd/svc.c | 80 ++++++++++++++++++++++++---------------------- include/linux/sunrpc/svc.h | 2 ++ 2 files changed, 44 insertions(+), 38 deletions(-) diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 55505cbe11af..5b1efe509fcc 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c @@ -122,58 +122,55 @@ static void restart_grace(void) } /* - * This is the lockd kernel thread + * Lockd kernel thread implementation using the iterant API + * We don't terminate until the last NFS mount or NFS daemon + * has gone away. */ -static int -lockd(void *vrqstp) +static void lockd_sigkill(int sig) { - int err = 0; - struct svc_rqst *rqstp = vrqstp; - - /* try_to_freeze() is called from svc_recv() */ - set_freezable(); + restart_grace(); +} +static void lockd_init(void *vrqstp) +{ /* Allow SIGKILL to tell lockd to drop all of its locks */ - allow_signal(SIGKILL); + kthread_sigaction(SIGKILL, lockd_sigkill); dprintk("NFS locking service started (ver " LOCKD_VERSION ").\n"); +} - /* - * The main request loop. We don't terminate until the last - * NFS mount or NFS daemon has gone away. - */ - while (!kthread_should_stop()) { - long timeout = MAX_SCHEDULE_TIMEOUT; - RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); +static void lockd_func(void *vrqstp) +{ + int err = 0; + struct svc_rqst *rqstp = vrqstp; - /* update sv_maxconn if it has changed */ - rqstp->rq_server->sv_maxconn = nlm_max_connections; + long timeout = MAX_SCHEDULE_TIMEOUT; + RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); - if (signalled()) { - flush_signals(current); - restart_grace(); - continue; - } + /* update sv_maxconn if it has changed */ + rqstp->rq_server->sv_maxconn = nlm_max_connections; - timeout = nlmsvc_retry_blocked(); + timeout = nlmsvc_retry_blocked(); - /* - * Find a socket with data available and call its - * recvfrom routine. - */ - err = svc_recv(rqstp, timeout); - if (err == -EAGAIN || err == -EINTR) - continue; - dprintk("lockd: request from %s\n", - svc_print_addr(rqstp, buf, sizeof(buf))); + /* + * Find a socket with data available and call its + * recvfrom routine. + */ + err = svc_recv(rqstp, timeout); + if (err == -EAGAIN || err == -EINTR) + return; - svc_process(rqstp); - } - flush_signals(current); + dprintk("lockd: request from %s\n", + svc_print_addr(rqstp, buf, sizeof(buf))); + + svc_process(rqstp); +} + +static void lockd_destroy(void *vrqstp) +{ if (nlmsvc_ops) nlmsvc_invalidate_all(); nlm_shutdown_hosts(); - return 0; } static int create_lockd_listener(struct svc_serv *serv, const char *name, @@ -301,7 +298,14 @@ static int lockd_start_svc(struct svc_serv *serv) svc_sock_update_bufs(serv); serv->sv_maxconn = nlm_max_connections; - nlmsvc_task = kthread_create(lockd, nlmsvc_rqst, "%s", serv->sv_name); + nlmsvc_rqst->rq_kti.type = 0; + nlmsvc_rqst->rq_kti.data = nlmsvc_rqst; + nlmsvc_rqst->rq_kti.init = lockd_init; + nlmsvc_rqst->rq_kti.func = lockd_func; + nlmsvc_rqst->rq_kti.destroy = lockd_destroy; + + nlmsvc_task = kthread_iterant_create(&nlmsvc_rqst->rq_kti, + "%s", serv->sv_name); if (IS_ERR(nlmsvc_task)) { error = PTR_ERR(nlmsvc_task); printk(KERN_WARNING diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index fae6fb947fc8..6275e9b9df9b 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -283,6 +284,7 @@ struct svc_rqst { struct auth_domain * rq_client; /* RPC peer info */ struct auth_domain * rq_gssclient; /* "gss/"-style peer info */ struct svc_cacherep * rq_cacherep; /* cache info */ + struct kthread_iterant rq_kti; /* info for iterant kthread */ struct task_struct *rq_task; /* service thread */ spinlock_t rq_lock; /* per-request lock */ };