struct filter_head {
        struct list_head        list;
-       struct rcu_head         rcu;
+       union {
+               struct rcu_head         rcu;
+               struct rcu_work         rwork;
+       };
 };
 
-
-static void free_filter_list(struct rcu_head *rhp)
+static void free_filter_list(struct filter_head *filter_list)
 {
-       struct filter_head *filter_list = container_of(rhp, struct filter_head, rcu);
        struct filter_list *filter_item, *tmp;
 
        list_for_each_entry_safe(filter_item, tmp, &filter_list->list, list) {
        kfree(filter_list);
 }
 
+static void free_filter_list_work(struct work_struct *work)
+{
+       struct filter_head *filter_list;
+
+       filter_list = container_of(to_rcu_work(work), struct filter_head, rwork);
+       free_filter_list(filter_list);
+}
+
 static void free_filter_list_tasks(struct rcu_head *rhp)
 {
-       call_rcu(rhp, free_filter_list);
+       struct filter_head *filter_list = container_of(rhp, struct filter_head, rcu);
+
+       INIT_RCU_WORK(&filter_list->rwork, free_filter_list_work);
+       queue_rcu_work(system_wq, &filter_list->rwork);
 }
 
 /*
        tracepoint_synchronize_unregister();
 
        if (head)
-               free_filter_list(&head->rcu);
+               free_filter_list(head);
 
        list_for_each_entry(file, &tr->events, list) {
                if (file->system != dir || !file->filter)
        return 0;
  fail:
        /* No call succeeded */
-       free_filter_list(&filter_list->rcu);
+       free_filter_list(filter_list);
        parse_error(pe, FILT_ERR_BAD_SUBSYS_FILTER, 0);
        return -EINVAL;
  fail_mem:
        if (!fail)
                delay_free_filter(filter_list);
        else
-               free_filter_list(&filter_list->rcu);
+               free_filter_list(filter_list);
 
        return -ENOMEM;
 }