1*8b712842SChris Mason /* 2*8b712842SChris Mason * Copyright (C) 2007 Oracle. All rights reserved. 3*8b712842SChris Mason * 4*8b712842SChris Mason * This program is free software; you can redistribute it and/or 5*8b712842SChris Mason * modify it under the terms of the GNU General Public 6*8b712842SChris Mason * License v2 as published by the Free Software Foundation. 7*8b712842SChris Mason * 8*8b712842SChris Mason * This program is distributed in the hope that it will be useful, 9*8b712842SChris Mason * but WITHOUT ANY WARRANTY; without even the implied warranty of 10*8b712842SChris Mason * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11*8b712842SChris Mason * General Public License for more details. 12*8b712842SChris Mason * 13*8b712842SChris Mason * You should have received a copy of the GNU General Public 14*8b712842SChris Mason * License along with this program; if not, write to the 15*8b712842SChris Mason * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 16*8b712842SChris Mason * Boston, MA 021110-1307, USA. 17*8b712842SChris Mason */ 18*8b712842SChris Mason 19*8b712842SChris Mason #ifndef __BTRFS_ASYNC_THREAD_ 20*8b712842SChris Mason #define __BTRFS_ASYNC_THREAD_ 21*8b712842SChris Mason 22*8b712842SChris Mason struct btrfs_worker_thread; 23*8b712842SChris Mason 24*8b712842SChris Mason /* 25*8b712842SChris Mason * This is similar to a workqueue, but it is meant to spread the operations 26*8b712842SChris Mason * across all available cpus instead of just the CPU that was used to 27*8b712842SChris Mason * queue the work. There is also some batching introduced to try and 28*8b712842SChris Mason * cut down on context switches. 29*8b712842SChris Mason * 30*8b712842SChris Mason * By default threads are added on demand up to 2 * the number of cpus. 31*8b712842SChris Mason * Changing struct btrfs_workers->max_workers is one way to prevent 32*8b712842SChris Mason * demand creation of kthreads. 33*8b712842SChris Mason * 34*8b712842SChris Mason * the basic model of these worker threads is to embed a btrfs_work 35*8b712842SChris Mason * structure in your own data struct, and use container_of in a 36*8b712842SChris Mason * work function to get back to your data struct. 37*8b712842SChris Mason */ 38*8b712842SChris Mason struct btrfs_work { 39*8b712842SChris Mason /* 40*8b712842SChris Mason * only func should be set to the function you want called 41*8b712842SChris Mason * your work struct is passed as the only arg 42*8b712842SChris Mason */ 43*8b712842SChris Mason void (*func)(struct btrfs_work *work); 44*8b712842SChris Mason 45*8b712842SChris Mason /* 46*8b712842SChris Mason * flags should be set to zero. It is used to make sure the 47*8b712842SChris Mason * struct is only inserted once into the list. 48*8b712842SChris Mason */ 49*8b712842SChris Mason unsigned long flags; 50*8b712842SChris Mason 51*8b712842SChris Mason /* don't touch these */ 52*8b712842SChris Mason struct btrfs_worker_thread *worker; 53*8b712842SChris Mason struct list_head list; 54*8b712842SChris Mason }; 55*8b712842SChris Mason 56*8b712842SChris Mason struct btrfs_workers { 57*8b712842SChris Mason /* current number of running workers */ 58*8b712842SChris Mason int num_workers; 59*8b712842SChris Mason 60*8b712842SChris Mason /* max number of workers allowed. changed by btrfs_start_workers */ 61*8b712842SChris Mason int max_workers; 62*8b712842SChris Mason 63*8b712842SChris Mason /* list with all the work threads */ 64*8b712842SChris Mason struct list_head worker_list; 65*8b712842SChris Mason 66*8b712842SChris Mason /* the last worker thread to have something queued */ 67*8b712842SChris Mason struct btrfs_worker_thread *last; 68*8b712842SChris Mason 69*8b712842SChris Mason /* lock for finding the next worker thread to queue on */ 70*8b712842SChris Mason spinlock_t lock; 71*8b712842SChris Mason }; 72*8b712842SChris Mason 73*8b712842SChris Mason int btrfs_queue_worker(struct btrfs_workers *workers, struct btrfs_work *work); 74*8b712842SChris Mason int btrfs_start_workers(struct btrfs_workers *workers, int num_workers); 75*8b712842SChris Mason int btrfs_stop_workers(struct btrfs_workers *workers); 76*8b712842SChris Mason void btrfs_init_workers(struct btrfs_workers *workers, int max); 77*8b712842SChris Mason int btrfs_requeue_work(struct btrfs_work *work); 78*8b712842SChris Mason #endif 79