From owner-svn-src-head@freebsd.org Mon Dec 21 12:20:03 2015 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id CC0E3A4EA56; Mon, 21 Dec 2015 12:20:03 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 8F65718D3; Mon, 21 Dec 2015 12:20:03 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id tBLCK2qp037878; Mon, 21 Dec 2015 12:20:02 GMT (envelope-from hselasky@FreeBSD.org) Received: (from hselasky@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id tBLCK2gI037876; Mon, 21 Dec 2015 12:20:02 GMT (envelope-from hselasky@FreeBSD.org) Message-Id: <201512211220.tBLCK2gI037876@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: hselasky set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky Date: Mon, 21 Dec 2015 12:20:02 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r292544 - in head/sys/compat/linuxkpi/common: include/linux src X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 21 Dec 2015 12:20:04 -0000 Author: hselasky Date: Mon Dec 21 12:20:02 2015 New Revision: 292544 URL: https://svnweb.freebsd.org/changeset/base/292544 Log: Implement drain_workqueue() function. MFC after: 1 week Sponsored by: Mellanox Technologies Modified: head/sys/compat/linuxkpi/common/include/linux/workqueue.h head/sys/compat/linuxkpi/common/src/linux_compat.c Modified: head/sys/compat/linuxkpi/common/include/linux/workqueue.h ============================================================================== --- head/sys/compat/linuxkpi/common/include/linux/workqueue.h Mon Dec 21 12:13:03 2015 (r292543) +++ head/sys/compat/linuxkpi/common/include/linux/workqueue.h Mon Dec 21 12:20:02 2015 (r292544) @@ -36,10 +36,13 @@ #include #include +#include + #include struct workqueue_struct { struct taskqueue *taskqueue; + atomic_t draining; }; struct work_struct { @@ -95,6 +98,9 @@ static inline int queue_work(struct workqueue_struct *wq, struct work_struct *work) { work->taskqueue = wq->taskqueue; + /* Check for draining */ + if (atomic_read(&wq->draining) != 0) + return (!work->work_task.ta_pending); /* Return opposite value to align with Linux logic */ return (!taskqueue_enqueue(wq->taskqueue, &work->work_task)); } @@ -106,7 +112,9 @@ queue_delayed_work(struct workqueue_stru int pending; work->work.taskqueue = wq->taskqueue; - if (delay != 0) { + if (atomic_read(&wq->draining) != 0) { + pending = work->work.work_task.ta_pending; + } else if (delay != 0) { pending = work->work.work_task.ta_pending; callout_reset(&work->timer, delay, linux_delayed_work_fn, work); } else { @@ -124,6 +132,7 @@ schedule_delayed_work(struct delayed_wor struct workqueue_struct wq; wq.taskqueue = taskqueue_thread; + atomic_set(&wq.draining, 0); return (queue_delayed_work(&wq, dwork, delay)); } @@ -153,6 +162,14 @@ flush_taskqueue(struct taskqueue *tq) PRELE(curproc); } +static inline void +drain_workqueue(struct workqueue_struct *wq) +{ + atomic_inc(&wq->draining); + flush_taskqueue(wq->taskqueue); + atomic_dec(&wq->draining); +} + static inline int cancel_work_sync(struct work_struct *work) { Modified: head/sys/compat/linuxkpi/common/src/linux_compat.c ============================================================================== --- head/sys/compat/linuxkpi/common/src/linux_compat.c Mon Dec 21 12:13:03 2015 (r292543) +++ head/sys/compat/linuxkpi/common/src/linux_compat.c Mon Dec 21 12:20:02 2015 (r292544) @@ -945,6 +945,7 @@ linux_create_workqueue_common(const char wq = kmalloc(sizeof(*wq), M_WAITOK); wq->taskqueue = taskqueue_create(name, M_WAITOK, taskqueue_thread_enqueue, &wq->taskqueue); + atomic_set(&wq->draining, 0); taskqueue_start_threads(&wq->taskqueue, cpus, PWAIT, "%s", name); return (wq);