aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/async-thread.c
diff options
context:
space:
mode:
authorQu Wenruo <quwenruo@cn.fujitsu.com>2014-02-27 21:46:04 -0500
committerJosef Bacik <jbacik@fb.com>2014-03-10 15:17:03 -0400
commit1ca08976ae94f3594dd7303584581cf8099ce47e (patch)
tree36266c4bd75ea9807f8936c40d1e13803b3fd83a /fs/btrfs/async-thread.c
parent08a9ff3264181986d1d692a4e6fce3669700c9f8 (diff)
btrfs: Add high priority workqueue support for btrfs_workqueue_struct
Add high priority function to btrfs_workqueue. This is implemented by embedding a btrfs_workqueue into a btrfs_workqueue and use some helper functions to differ the normal priority wq and high priority wq. So the high priority wq is completely independent from the normal workqueue. Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com> Tested-by: David Sterba <dsterba@suse.cz> Signed-off-by: Josef Bacik <jbacik@fb.com>
Diffstat (limited to 'fs/btrfs/async-thread.c')
-rw-r--r--fs/btrfs/async-thread.c91
1 files changed, 79 insertions, 12 deletions
diff --git a/fs/btrfs/async-thread.c b/fs/btrfs/async-thread.c
index 905de02e4386..193c84964db9 100644
--- a/fs/btrfs/async-thread.c
+++ b/fs/btrfs/async-thread.c
@@ -730,7 +730,7 @@ void btrfs_queue_worker(struct btrfs_workers *workers, struct btrfs_work *work)
730 spin_unlock_irqrestore(&worker->lock, flags); 730 spin_unlock_irqrestore(&worker->lock, flags);
731} 731}
732 732
733struct btrfs_workqueue_struct { 733struct __btrfs_workqueue_struct {
734 struct workqueue_struct *normal_wq; 734 struct workqueue_struct *normal_wq;
735 /* List head pointing to ordered work list */ 735 /* List head pointing to ordered work list */
736 struct list_head ordered_list; 736 struct list_head ordered_list;
@@ -739,6 +739,38 @@ struct btrfs_workqueue_struct {
739 spinlock_t list_lock; 739 spinlock_t list_lock;
740}; 740};
741 741
742struct btrfs_workqueue_struct {
743 struct __btrfs_workqueue_struct *normal;
744 struct __btrfs_workqueue_struct *high;
745};
746
747static inline struct __btrfs_workqueue_struct
748*__btrfs_alloc_workqueue(char *name, int flags, int max_active)
749{
750 struct __btrfs_workqueue_struct *ret = kzalloc(sizeof(*ret), GFP_NOFS);
751
752 if (unlikely(!ret))
753 return NULL;
754
755 if (flags & WQ_HIGHPRI)
756 ret->normal_wq = alloc_workqueue("%s-%s-high", flags,
757 max_active, "btrfs", name);
758 else
759 ret->normal_wq = alloc_workqueue("%s-%s", flags,
760 max_active, "btrfs", name);
761 if (unlikely(!ret->normal_wq)) {
762 kfree(ret);
763 return NULL;
764 }
765
766 INIT_LIST_HEAD(&ret->ordered_list);
767 spin_lock_init(&ret->list_lock);
768 return ret;
769}
770
771static inline void
772__btrfs_destroy_workqueue(struct __btrfs_workqueue_struct *wq);
773
742struct btrfs_workqueue_struct *btrfs_alloc_workqueue(char *name, 774struct btrfs_workqueue_struct *btrfs_alloc_workqueue(char *name,
743 int flags, 775 int flags,
744 int max_active) 776 int max_active)
@@ -748,19 +780,25 @@ struct btrfs_workqueue_struct *btrfs_alloc_workqueue(char *name,
748 if (unlikely(!ret)) 780 if (unlikely(!ret))
749 return NULL; 781 return NULL;
750 782
751 ret->normal_wq = alloc_workqueue("%s-%s", flags, max_active, 783 ret->normal = __btrfs_alloc_workqueue(name, flags & ~WQ_HIGHPRI,
752 "btrfs", name); 784 max_active);
753 if (unlikely(!ret->normal_wq)) { 785 if (unlikely(!ret->normal)) {
754 kfree(ret); 786 kfree(ret);
755 return NULL; 787 return NULL;
756 } 788 }
757 789
758 INIT_LIST_HEAD(&ret->ordered_list); 790 if (flags & WQ_HIGHPRI) {
759 spin_lock_init(&ret->list_lock); 791 ret->high = __btrfs_alloc_workqueue(name, flags, max_active);
792 if (unlikely(!ret->high)) {
793 __btrfs_destroy_workqueue(ret->normal);
794 kfree(ret);
795 return NULL;
796 }
797 }
760 return ret; 798 return ret;
761} 799}
762 800
763static void run_ordered_work(struct btrfs_workqueue_struct *wq) 801static void run_ordered_work(struct __btrfs_workqueue_struct *wq)
764{ 802{
765 struct list_head *list = &wq->ordered_list; 803 struct list_head *list = &wq->ordered_list;
766 struct btrfs_work_struct *work; 804 struct btrfs_work_struct *work;
@@ -804,7 +842,7 @@ static void run_ordered_work(struct btrfs_workqueue_struct *wq)
804static void normal_work_helper(struct work_struct *arg) 842static void normal_work_helper(struct work_struct *arg)
805{ 843{
806 struct btrfs_work_struct *work; 844 struct btrfs_work_struct *work;
807 struct btrfs_workqueue_struct *wq; 845 struct __btrfs_workqueue_struct *wq;
808 int need_order = 0; 846 int need_order = 0;
809 847
810 work = container_of(arg, struct btrfs_work_struct, normal_work); 848 work = container_of(arg, struct btrfs_work_struct, normal_work);
@@ -840,8 +878,8 @@ void btrfs_init_work(struct btrfs_work_struct *work,
840 work->flags = 0; 878 work->flags = 0;
841} 879}
842 880
843void btrfs_queue_work(struct btrfs_workqueue_struct *wq, 881static inline void __btrfs_queue_work(struct __btrfs_workqueue_struct *wq,
844 struct btrfs_work_struct *work) 882 struct btrfs_work_struct *work)
845{ 883{
846 unsigned long flags; 884 unsigned long flags;
847 885
@@ -854,13 +892,42 @@ void btrfs_queue_work(struct btrfs_workqueue_struct *wq,
854 queue_work(wq->normal_wq, &work->normal_work); 892 queue_work(wq->normal_wq, &work->normal_work);
855} 893}
856 894
857void btrfs_destroy_workqueue(struct btrfs_workqueue_struct *wq) 895void btrfs_queue_work(struct btrfs_workqueue_struct *wq,
896 struct btrfs_work_struct *work)
897{
898 struct __btrfs_workqueue_struct *dest_wq;
899
900 if (test_bit(WORK_HIGH_PRIO_BIT, &work->flags) && wq->high)
901 dest_wq = wq->high;
902 else
903 dest_wq = wq->normal;
904 __btrfs_queue_work(dest_wq, work);
905}
906
907static inline void
908__btrfs_destroy_workqueue(struct __btrfs_workqueue_struct *wq)
858{ 909{
859 destroy_workqueue(wq->normal_wq); 910 destroy_workqueue(wq->normal_wq);
860 kfree(wq); 911 kfree(wq);
861} 912}
862 913
914void btrfs_destroy_workqueue(struct btrfs_workqueue_struct *wq)
915{
916 if (!wq)
917 return;
918 if (wq->high)
919 __btrfs_destroy_workqueue(wq->high);
920 __btrfs_destroy_workqueue(wq->normal);
921}
922
863void btrfs_workqueue_set_max(struct btrfs_workqueue_struct *wq, int max) 923void btrfs_workqueue_set_max(struct btrfs_workqueue_struct *wq, int max)
864{ 924{
865 workqueue_set_max_active(wq->normal_wq, max); 925 workqueue_set_max_active(wq->normal->normal_wq, max);
926 if (wq->high)
927 workqueue_set_max_active(wq->high->normal_wq, max);
928}
929
930void btrfs_set_work_high_priority(struct btrfs_work_struct *work)
931{
932 set_bit(WORK_HIGH_PRIO_BIT, &work->flags);
866} 933}