aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2010-12-20 20:02:25 -0500
committerDave Chinner <david@fromorbit.com>2010-12-20 20:02:25 -0500
commit1054794198e39103cb986618c4c10ec2252b7089 (patch)
treebc1d6a3eece9385bef892c2df7d6dba6f39d3088 /fs/xfs
parent9552e7f2f3dd13a7580e488a7a3582332daad4f5 (diff)
xfs: convert log grant ticket queues to list heads
The grant write and reserve queues use a roll-your-own double linked list, so convert it to a standard list_head structure and convert all the list traversals to use list_for_each_entry(). We can also get rid of the XLOG_TIC_IN_Q flag as we can use the list_empty() check to tell if the ticket is in a list or not. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/linux-2.6/xfs_trace.h16
-rw-r--r--fs/xfs/xfs_log.c123
-rw-r--r--fs/xfs/xfs_log_priv.h11
3 files changed, 53 insertions, 97 deletions
diff --git a/fs/xfs/linux-2.6/xfs_trace.h b/fs/xfs/linux-2.6/xfs_trace.h
index 83e8760159e..69b9e1f1baa 100644
--- a/fs/xfs/linux-2.6/xfs_trace.h
+++ b/fs/xfs/linux-2.6/xfs_trace.h
@@ -766,8 +766,8 @@ DECLARE_EVENT_CLASS(xfs_loggrant_class,
766 __field(int, curr_res) 766 __field(int, curr_res)
767 __field(int, unit_res) 767 __field(int, unit_res)
768 __field(unsigned int, flags) 768 __field(unsigned int, flags)
769 __field(void *, reserve_headq) 769 __field(int, reserveq)
770 __field(void *, write_headq) 770 __field(int, writeq)
771 __field(int, grant_reserve_cycle) 771 __field(int, grant_reserve_cycle)
772 __field(int, grant_reserve_bytes) 772 __field(int, grant_reserve_bytes)
773 __field(int, grant_write_cycle) 773 __field(int, grant_write_cycle)
@@ -784,8 +784,8 @@ DECLARE_EVENT_CLASS(xfs_loggrant_class,
784 __entry->curr_res = tic->t_curr_res; 784 __entry->curr_res = tic->t_curr_res;
785 __entry->unit_res = tic->t_unit_res; 785 __entry->unit_res = tic->t_unit_res;
786 __entry->flags = tic->t_flags; 786 __entry->flags = tic->t_flags;
787 __entry->reserve_headq = log->l_reserve_headq; 787 __entry->reserveq = list_empty(&log->l_reserveq);
788 __entry->write_headq = log->l_write_headq; 788 __entry->writeq = list_empty(&log->l_writeq);
789 __entry->grant_reserve_cycle = log->l_grant_reserve_cycle; 789 __entry->grant_reserve_cycle = log->l_grant_reserve_cycle;
790 __entry->grant_reserve_bytes = log->l_grant_reserve_bytes; 790 __entry->grant_reserve_bytes = log->l_grant_reserve_bytes;
791 __entry->grant_write_cycle = log->l_grant_write_cycle; 791 __entry->grant_write_cycle = log->l_grant_write_cycle;
@@ -795,8 +795,8 @@ DECLARE_EVENT_CLASS(xfs_loggrant_class,
795 __entry->tail_lsn = log->l_tail_lsn; 795 __entry->tail_lsn = log->l_tail_lsn;
796 ), 796 ),
797 TP_printk("dev %d:%d type %s t_ocnt %u t_cnt %u t_curr_res %u " 797 TP_printk("dev %d:%d type %s t_ocnt %u t_cnt %u t_curr_res %u "
798 "t_unit_res %u t_flags %s reserve_headq 0x%p " 798 "t_unit_res %u t_flags %s reserveq %s "
799 "write_headq 0x%p grant_reserve_cycle %d " 799 "writeq %s grant_reserve_cycle %d "
800 "grant_reserve_bytes %d grant_write_cycle %d " 800 "grant_reserve_bytes %d grant_write_cycle %d "
801 "grant_write_bytes %d curr_cycle %d curr_block %d " 801 "grant_write_bytes %d curr_cycle %d curr_block %d "
802 "tail_cycle %d tail_block %d", 802 "tail_cycle %d tail_block %d",
@@ -807,8 +807,8 @@ DECLARE_EVENT_CLASS(xfs_loggrant_class,
807 __entry->curr_res, 807 __entry->curr_res,
808 __entry->unit_res, 808 __entry->unit_res,
809 __print_flags(__entry->flags, "|", XLOG_TIC_FLAGS), 809 __print_flags(__entry->flags, "|", XLOG_TIC_FLAGS),
810 __entry->reserve_headq, 810 __entry->reserveq ? "empty" : "active",
811 __entry->write_headq, 811 __entry->writeq ? "empty" : "active",
812 __entry->grant_reserve_cycle, 812 __entry->grant_reserve_cycle,
813 __entry->grant_reserve_bytes, 813 __entry->grant_reserve_bytes,
814 __entry->grant_write_cycle, 814 __entry->grant_write_cycle,
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index cee4ab9f8a9..1b82735471a 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -95,38 +95,6 @@ STATIC void xlog_verify_tail_lsn(xlog_t *log, xlog_in_core_t *iclog,
95 95
96STATIC int xlog_iclogs_empty(xlog_t *log); 96STATIC int xlog_iclogs_empty(xlog_t *log);
97 97
98
99static void
100xlog_ins_ticketq(struct xlog_ticket **qp, struct xlog_ticket *tic)
101{
102 if (*qp) {
103 tic->t_next = (*qp);
104 tic->t_prev = (*qp)->t_prev;
105 (*qp)->t_prev->t_next = tic;
106 (*qp)->t_prev = tic;
107 } else {
108 tic->t_prev = tic->t_next = tic;
109 *qp = tic;
110 }
111
112 tic->t_flags |= XLOG_TIC_IN_Q;
113}
114
115static void
116xlog_del_ticketq(struct xlog_ticket **qp, struct xlog_ticket *tic)
117{
118 if (tic == tic->t_next) {
119 *qp = NULL;
120 } else {
121 *qp = tic->t_next;
122 tic->t_next->t_prev = tic->t_prev;
123 tic->t_prev->t_next = tic->t_next;
124 }
125
126 tic->t_next = tic->t_prev = NULL;
127 tic->t_flags &= ~XLOG_TIC_IN_Q;
128}
129
130static void 98static void
131xlog_grant_sub_space(struct log *log, int bytes) 99xlog_grant_sub_space(struct log *log, int bytes)
132{ 100{
@@ -724,7 +692,7 @@ xfs_log_move_tail(xfs_mount_t *mp,
724 log->l_tail_lsn = tail_lsn; 692 log->l_tail_lsn = tail_lsn;
725 } 693 }
726 694
727 if ((tic = log->l_write_headq)) { 695 if (!list_empty(&log->l_writeq)) {
728#ifdef DEBUG 696#ifdef DEBUG
729 if (log->l_flags & XLOG_ACTIVE_RECOVERY) 697 if (log->l_flags & XLOG_ACTIVE_RECOVERY)
730 panic("Recovery problem"); 698 panic("Recovery problem");
@@ -732,7 +700,7 @@ xfs_log_move_tail(xfs_mount_t *mp,
732 cycle = log->l_grant_write_cycle; 700 cycle = log->l_grant_write_cycle;
733 bytes = log->l_grant_write_bytes; 701 bytes = log->l_grant_write_bytes;
734 free_bytes = xlog_space_left(log, cycle, bytes); 702 free_bytes = xlog_space_left(log, cycle, bytes);
735 do { 703 list_for_each_entry(tic, &log->l_writeq, t_queue) {
736 ASSERT(tic->t_flags & XLOG_TIC_PERM_RESERV); 704 ASSERT(tic->t_flags & XLOG_TIC_PERM_RESERV);
737 705
738 if (free_bytes < tic->t_unit_res && tail_lsn != 1) 706 if (free_bytes < tic->t_unit_res && tail_lsn != 1)
@@ -740,10 +708,10 @@ xfs_log_move_tail(xfs_mount_t *mp,
740 tail_lsn = 0; 708 tail_lsn = 0;
741 free_bytes -= tic->t_unit_res; 709 free_bytes -= tic->t_unit_res;
742 sv_signal(&tic->t_wait); 710 sv_signal(&tic->t_wait);
743 tic = tic->t_next; 711 }
744 } while (tic != log->l_write_headq);
745 } 712 }
746 if ((tic = log->l_reserve_headq)) { 713
714 if (!list_empty(&log->l_reserveq)) {
747#ifdef DEBUG 715#ifdef DEBUG
748 if (log->l_flags & XLOG_ACTIVE_RECOVERY) 716 if (log->l_flags & XLOG_ACTIVE_RECOVERY)
749 panic("Recovery problem"); 717 panic("Recovery problem");
@@ -751,7 +719,7 @@ xfs_log_move_tail(xfs_mount_t *mp,
751 cycle = log->l_grant_reserve_cycle; 719 cycle = log->l_grant_reserve_cycle;
752 bytes = log->l_grant_reserve_bytes; 720 bytes = log->l_grant_reserve_bytes;
753 free_bytes = xlog_space_left(log, cycle, bytes); 721 free_bytes = xlog_space_left(log, cycle, bytes);
754 do { 722 list_for_each_entry(tic, &log->l_reserveq, t_queue) {
755 if (tic->t_flags & XLOG_TIC_PERM_RESERV) 723 if (tic->t_flags & XLOG_TIC_PERM_RESERV)
756 need_bytes = tic->t_unit_res*tic->t_cnt; 724 need_bytes = tic->t_unit_res*tic->t_cnt;
757 else 725 else
@@ -761,8 +729,7 @@ xfs_log_move_tail(xfs_mount_t *mp,
761 tail_lsn = 0; 729 tail_lsn = 0;
762 free_bytes -= need_bytes; 730 free_bytes -= need_bytes;
763 sv_signal(&tic->t_wait); 731 sv_signal(&tic->t_wait);
764 tic = tic->t_next; 732 }
765 } while (tic != log->l_reserve_headq);
766 } 733 }
767 spin_unlock(&log->l_grant_lock); 734 spin_unlock(&log->l_grant_lock);
768} /* xfs_log_move_tail */ 735} /* xfs_log_move_tail */
@@ -1053,6 +1020,8 @@ xlog_alloc_log(xfs_mount_t *mp,
1053 log->l_curr_cycle = 1; /* 0 is bad since this is initial value */ 1020 log->l_curr_cycle = 1; /* 0 is bad since this is initial value */
1054 log->l_grant_reserve_cycle = 1; 1021 log->l_grant_reserve_cycle = 1;
1055 log->l_grant_write_cycle = 1; 1022 log->l_grant_write_cycle = 1;
1023 INIT_LIST_HEAD(&log->l_reserveq);
1024 INIT_LIST_HEAD(&log->l_writeq);
1056 1025
1057 error = EFSCORRUPTED; 1026 error = EFSCORRUPTED;
1058 if (xfs_sb_version_hassector(&mp->m_sb)) { 1027 if (xfs_sb_version_hassector(&mp->m_sb)) {
@@ -2550,8 +2519,8 @@ xlog_grant_log_space(xlog_t *log,
2550 trace_xfs_log_grant_enter(log, tic); 2519 trace_xfs_log_grant_enter(log, tic);
2551 2520
2552 /* something is already sleeping; insert new transaction at end */ 2521 /* something is already sleeping; insert new transaction at end */
2553 if (log->l_reserve_headq) { 2522 if (!list_empty(&log->l_reserveq)) {
2554 xlog_ins_ticketq(&log->l_reserve_headq, tic); 2523 list_add_tail(&tic->t_queue, &log->l_reserveq);
2555 2524
2556 trace_xfs_log_grant_sleep1(log, tic); 2525 trace_xfs_log_grant_sleep1(log, tic);
2557 2526
@@ -2583,8 +2552,8 @@ redo:
2583 free_bytes = xlog_space_left(log, log->l_grant_reserve_cycle, 2552 free_bytes = xlog_space_left(log, log->l_grant_reserve_cycle,
2584 log->l_grant_reserve_bytes); 2553 log->l_grant_reserve_bytes);
2585 if (free_bytes < need_bytes) { 2554 if (free_bytes < need_bytes) {
2586 if ((tic->t_flags & XLOG_TIC_IN_Q) == 0) 2555 if (list_empty(&tic->t_queue))
2587 xlog_ins_ticketq(&log->l_reserve_headq, tic); 2556 list_add_tail(&tic->t_queue, &log->l_reserveq);
2588 2557
2589 trace_xfs_log_grant_sleep2(log, tic); 2558 trace_xfs_log_grant_sleep2(log, tic);
2590 2559
@@ -2602,8 +2571,9 @@ redo:
2602 trace_xfs_log_grant_wake2(log, tic); 2571 trace_xfs_log_grant_wake2(log, tic);
2603 2572
2604 goto redo; 2573 goto redo;
2605 } else if (tic->t_flags & XLOG_TIC_IN_Q) 2574 }
2606 xlog_del_ticketq(&log->l_reserve_headq, tic); 2575
2576 list_del_init(&tic->t_queue);
2607 2577
2608 /* we've got enough space */ 2578 /* we've got enough space */
2609 xlog_grant_add_space(log, need_bytes); 2579 xlog_grant_add_space(log, need_bytes);
@@ -2626,9 +2596,7 @@ redo:
2626 return 0; 2596 return 0;
2627 2597
2628 error_return: 2598 error_return:
2629 if (tic->t_flags & XLOG_TIC_IN_Q) 2599 list_del_init(&tic->t_queue);
2630 xlog_del_ticketq(&log->l_reserve_headq, tic);
2631
2632 trace_xfs_log_grant_error(log, tic); 2600 trace_xfs_log_grant_error(log, tic);
2633 2601
2634 /* 2602 /*
@@ -2653,7 +2621,6 @@ xlog_regrant_write_log_space(xlog_t *log,
2653 xlog_ticket_t *tic) 2621 xlog_ticket_t *tic)
2654{ 2622{
2655 int free_bytes, need_bytes; 2623 int free_bytes, need_bytes;
2656 xlog_ticket_t *ntic;
2657#ifdef DEBUG 2624#ifdef DEBUG
2658 xfs_lsn_t tail_lsn; 2625 xfs_lsn_t tail_lsn;
2659#endif 2626#endif
@@ -2683,22 +2650,23 @@ xlog_regrant_write_log_space(xlog_t *log,
2683 * this transaction. 2650 * this transaction.
2684 */ 2651 */
2685 need_bytes = tic->t_unit_res; 2652 need_bytes = tic->t_unit_res;
2686 if ((ntic = log->l_write_headq)) { 2653 if (!list_empty(&log->l_writeq)) {
2654 struct xlog_ticket *ntic;
2687 free_bytes = xlog_space_left(log, log->l_grant_write_cycle, 2655 free_bytes = xlog_space_left(log, log->l_grant_write_cycle,
2688 log->l_grant_write_bytes); 2656 log->l_grant_write_bytes);
2689 do { 2657 list_for_each_entry(ntic, &log->l_writeq, t_queue) {
2690 ASSERT(ntic->t_flags & XLOG_TIC_PERM_RESERV); 2658 ASSERT(ntic->t_flags & XLOG_TIC_PERM_RESERV);
2691 2659
2692 if (free_bytes < ntic->t_unit_res) 2660 if (free_bytes < ntic->t_unit_res)
2693 break; 2661 break;
2694 free_bytes -= ntic->t_unit_res; 2662 free_bytes -= ntic->t_unit_res;
2695 sv_signal(&ntic->t_wait); 2663 sv_signal(&ntic->t_wait);
2696 ntic = ntic->t_next; 2664 }
2697 } while (ntic != log->l_write_headq);
2698 2665
2699 if (ntic != log->l_write_headq) { 2666 if (ntic != list_first_entry(&log->l_writeq,
2700 if ((tic->t_flags & XLOG_TIC_IN_Q) == 0) 2667 struct xlog_ticket, t_queue)) {
2701 xlog_ins_ticketq(&log->l_write_headq, tic); 2668 if (list_empty(&tic->t_queue))
2669 list_add_tail(&tic->t_queue, &log->l_writeq);
2702 2670
2703 trace_xfs_log_regrant_write_sleep1(log, tic); 2671 trace_xfs_log_regrant_write_sleep1(log, tic);
2704 2672
@@ -2727,8 +2695,8 @@ redo:
2727 free_bytes = xlog_space_left(log, log->l_grant_write_cycle, 2695 free_bytes = xlog_space_left(log, log->l_grant_write_cycle,
2728 log->l_grant_write_bytes); 2696 log->l_grant_write_bytes);
2729 if (free_bytes < need_bytes) { 2697 if (free_bytes < need_bytes) {
2730 if ((tic->t_flags & XLOG_TIC_IN_Q) == 0) 2698 if (list_empty(&tic->t_queue))
2731 xlog_ins_ticketq(&log->l_write_headq, tic); 2699 list_add_tail(&tic->t_queue, &log->l_writeq);
2732 spin_unlock(&log->l_grant_lock); 2700 spin_unlock(&log->l_grant_lock);
2733 xlog_grant_push_ail(log->l_mp, need_bytes); 2701 xlog_grant_push_ail(log->l_mp, need_bytes);
2734 spin_lock(&log->l_grant_lock); 2702 spin_lock(&log->l_grant_lock);
@@ -2745,8 +2713,9 @@ redo:
2745 2713
2746 trace_xfs_log_regrant_write_wake2(log, tic); 2714 trace_xfs_log_regrant_write_wake2(log, tic);
2747 goto redo; 2715 goto redo;
2748 } else if (tic->t_flags & XLOG_TIC_IN_Q) 2716 }
2749 xlog_del_ticketq(&log->l_write_headq, tic); 2717
2718 list_del_init(&tic->t_queue);
2750 2719
2751 /* we've got enough space */ 2720 /* we've got enough space */
2752 xlog_grant_add_space_write(log, need_bytes); 2721 xlog_grant_add_space_write(log, need_bytes);
@@ -2766,9 +2735,7 @@ redo:
2766 2735
2767 2736
2768 error_return: 2737 error_return:
2769 if (tic->t_flags & XLOG_TIC_IN_Q) 2738 list_del_init(&tic->t_queue);
2770 xlog_del_ticketq(&log->l_reserve_headq, tic);
2771
2772 trace_xfs_log_regrant_write_error(log, tic); 2739 trace_xfs_log_regrant_write_error(log, tic);
2773 2740
2774 /* 2741 /*
@@ -3435,6 +3402,7 @@ xlog_ticket_alloc(
3435 } 3402 }
3436 3403
3437 atomic_set(&tic->t_ref, 1); 3404 atomic_set(&tic->t_ref, 1);
3405 INIT_LIST_HEAD(&tic->t_queue);
3438 tic->t_unit_res = unit_bytes; 3406 tic->t_unit_res = unit_bytes;
3439 tic->t_curr_res = unit_bytes; 3407 tic->t_curr_res = unit_bytes;
3440 tic->t_cnt = cnt; 3408 tic->t_cnt = cnt;
@@ -3742,26 +3710,17 @@ xfs_log_force_umount(
3742 spin_unlock(&log->l_icloglock); 3710 spin_unlock(&log->l_icloglock);
3743 3711
3744 /* 3712 /*
3745 * We don't want anybody waiting for log reservations 3713 * We don't want anybody waiting for log reservations after this. That
3746 * after this. That means we have to wake up everybody 3714 * means we have to wake up everybody queued up on reserveq as well as
3747 * queued up on reserve_headq as well as write_headq. 3715 * writeq. In addition, we make sure in xlog_{re}grant_log_space that
3748 * In addition, we make sure in xlog_{re}grant_log_space 3716 * we don't enqueue anything once the SHUTDOWN flag is set, and this
3749 * that we don't enqueue anything once the SHUTDOWN flag 3717 * action is protected by the GRANTLOCK.
3750 * is set, and this action is protected by the GRANTLOCK.
3751 */ 3718 */
3752 if ((tic = log->l_reserve_headq)) { 3719 list_for_each_entry(tic, &log->l_reserveq, t_queue)
3753 do { 3720 sv_signal(&tic->t_wait);
3754 sv_signal(&tic->t_wait);
3755 tic = tic->t_next;
3756 } while (tic != log->l_reserve_headq);
3757 }
3758 3721
3759 if ((tic = log->l_write_headq)) { 3722 list_for_each_entry(tic, &log->l_writeq, t_queue)
3760 do { 3723 sv_signal(&tic->t_wait);
3761 sv_signal(&tic->t_wait);
3762 tic = tic->t_next;
3763 } while (tic != log->l_write_headq);
3764 }
3765 spin_unlock(&log->l_grant_lock); 3724 spin_unlock(&log->l_grant_lock);
3766 3725
3767 if (!(log->l_iclog->ic_state & XLOG_STATE_IOERROR)) { 3726 if (!(log->l_iclog->ic_state & XLOG_STATE_IOERROR)) {
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h
index c1ce505313e..a5b3c021a40 100644
--- a/fs/xfs/xfs_log_priv.h
+++ b/fs/xfs/xfs_log_priv.h
@@ -132,12 +132,10 @@ static inline uint xlog_get_client_id(__be32 i)
132 */ 132 */
133#define XLOG_TIC_INITED 0x1 /* has been initialized */ 133#define XLOG_TIC_INITED 0x1 /* has been initialized */
134#define XLOG_TIC_PERM_RESERV 0x2 /* permanent reservation */ 134#define XLOG_TIC_PERM_RESERV 0x2 /* permanent reservation */
135#define XLOG_TIC_IN_Q 0x4
136 135
137#define XLOG_TIC_FLAGS \ 136#define XLOG_TIC_FLAGS \
138 { XLOG_TIC_INITED, "XLOG_TIC_INITED" }, \ 137 { XLOG_TIC_INITED, "XLOG_TIC_INITED" }, \
139 { XLOG_TIC_PERM_RESERV, "XLOG_TIC_PERM_RESERV" }, \ 138 { XLOG_TIC_PERM_RESERV, "XLOG_TIC_PERM_RESERV" }
140 { XLOG_TIC_IN_Q, "XLOG_TIC_IN_Q" }
141 139
142#endif /* __KERNEL__ */ 140#endif /* __KERNEL__ */
143 141
@@ -244,8 +242,7 @@ typedef struct xlog_res {
244 242
245typedef struct xlog_ticket { 243typedef struct xlog_ticket {
246 sv_t t_wait; /* ticket wait queue : 20 */ 244 sv_t t_wait; /* ticket wait queue : 20 */
247 struct xlog_ticket *t_next; /* :4|8 */ 245 struct list_head t_queue; /* reserve/write queue */
248 struct xlog_ticket *t_prev; /* :4|8 */
249 xlog_tid_t t_tid; /* transaction identifier : 4 */ 246 xlog_tid_t t_tid; /* transaction identifier : 4 */
250 atomic_t t_ref; /* ticket reference count : 4 */ 247 atomic_t t_ref; /* ticket reference count : 4 */
251 int t_curr_res; /* current reservation in bytes : 4 */ 248 int t_curr_res; /* current reservation in bytes : 4 */
@@ -519,8 +516,8 @@ typedef struct log {
519 516
520 /* The following block of fields are changed while holding grant_lock */ 517 /* The following block of fields are changed while holding grant_lock */
521 spinlock_t l_grant_lock ____cacheline_aligned_in_smp; 518 spinlock_t l_grant_lock ____cacheline_aligned_in_smp;
522 xlog_ticket_t *l_reserve_headq; 519 struct list_head l_reserveq;
523 xlog_ticket_t *l_write_headq; 520 struct list_head l_writeq;
524 int l_grant_reserve_cycle; 521 int l_grant_reserve_cycle;
525 int l_grant_reserve_bytes; 522 int l_grant_reserve_bytes;
526 int l_grant_write_cycle; 523 int l_grant_write_cycle;