Commit 9cabcdbd4638cf884839ee4cd15780800c223b90

Authored by Steven Whitehouse
1 parent 209806aba9

[GFS2] Replace rgrp "recent list" with mru list

This patch removes the "recent list" which is used during allocation
and replaces it with the (already existing) mru list used during
deletion. The "recent list" was not a true mru list leading to a number
of inefficiencies including a "next" function which made scanning the
list an order N^2 operation wrt to the number of list elements.

This should increase allocation performance with large numbers of rgrps.
Its also a useful preparation and cleanup before some further changes
which are planned in this area.

Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>

Showing 3 changed files with 12 additions and 99 deletions Side-by-side Diff

... ... @@ -77,7 +77,6 @@
77 77 struct gfs2_rgrpd {
78 78 struct list_head rd_list; /* Link with superblock */
79 79 struct list_head rd_list_mru;
80   - struct list_head rd_recent; /* Recently used rgrps */
81 80 struct gfs2_glock *rd_gl; /* Glock for this rgrp */
82 81 u64 rd_addr; /* grp block disk address */
83 82 u64 rd_data0; /* first data location */
... ... @@ -529,7 +528,6 @@
529 528 struct mutex sd_rindex_mutex;
530 529 struct list_head sd_rindex_list;
531 530 struct list_head sd_rindex_mru_list;
532   - struct list_head sd_rindex_recent_list;
533 531 struct gfs2_rgrpd *sd_rindex_forward;
534 532 unsigned int sd_rgrps;
535 533  
fs/gfs2/ops_fstype.c
... ... @@ -64,7 +64,6 @@
64 64 mutex_init(&sdp->sd_rindex_mutex);
65 65 INIT_LIST_HEAD(&sdp->sd_rindex_list);
66 66 INIT_LIST_HEAD(&sdp->sd_rindex_mru_list);
67   - INIT_LIST_HEAD(&sdp->sd_rindex_recent_list);
68 67  
69 68 INIT_LIST_HEAD(&sdp->sd_jindex_list);
70 69 spin_lock_init(&sdp->sd_jindex_spin);
... ... @@ -371,11 +371,6 @@
371 371  
372 372 spin_lock(&sdp->sd_rindex_spin);
373 373 sdp->sd_rindex_forward = NULL;
374   - head = &sdp->sd_rindex_recent_list;
375   - while (!list_empty(head)) {
376   - rgd = list_entry(head->next, struct gfs2_rgrpd, rd_recent);
377   - list_del(&rgd->rd_recent);
378   - }
379 374 spin_unlock(&sdp->sd_rindex_spin);
380 375  
381 376 head = &sdp->sd_rindex_list;
382 377  
383 378  
384 379  
385 380  
386 381  
... ... @@ -945,107 +940,30 @@
945 940 }
946 941  
947 942 /**
948   - * recent_rgrp_first - get first RG from "recent" list
949   - * @sdp: The GFS2 superblock
950   - * @rglast: address of the rgrp used last
951   - *
952   - * Returns: The first rgrp in the recent list
953   - */
954   -
955   -static struct gfs2_rgrpd *recent_rgrp_first(struct gfs2_sbd *sdp,
956   - u64 rglast)
957   -{
958   - struct gfs2_rgrpd *rgd;
959   -
960   - spin_lock(&sdp->sd_rindex_spin);
961   -
962   - if (rglast) {
963   - list_for_each_entry(rgd, &sdp->sd_rindex_recent_list, rd_recent) {
964   - if (rgrp_contains_block(rgd, rglast))
965   - goto out;
966   - }
967   - }
968   - rgd = NULL;
969   - if (!list_empty(&sdp->sd_rindex_recent_list))
970   - rgd = list_entry(sdp->sd_rindex_recent_list.next,
971   - struct gfs2_rgrpd, rd_recent);
972   -out:
973   - spin_unlock(&sdp->sd_rindex_spin);
974   - return rgd;
975   -}
976   -
977   -/**
978 943 * recent_rgrp_next - get next RG from "recent" list
979 944 * @cur_rgd: current rgrp
980   - * @remove:
981 945 *
982 946 * Returns: The next rgrp in the recent list
983 947 */
984 948  
985   -static struct gfs2_rgrpd *recent_rgrp_next(struct gfs2_rgrpd *cur_rgd,
986   - int remove)
  949 +static struct gfs2_rgrpd *recent_rgrp_next(struct gfs2_rgrpd *cur_rgd)
987 950 {
988 951 struct gfs2_sbd *sdp = cur_rgd->rd_sbd;
989 952 struct list_head *head;
990 953 struct gfs2_rgrpd *rgd;
991 954  
992 955 spin_lock(&sdp->sd_rindex_spin);
993   -
994   - head = &sdp->sd_rindex_recent_list;
995   -
996   - list_for_each_entry(rgd, head, rd_recent) {
997   - if (rgd == cur_rgd) {
998   - if (cur_rgd->rd_recent.next != head)
999   - rgd = list_entry(cur_rgd->rd_recent.next,
1000   - struct gfs2_rgrpd, rd_recent);
1001   - else
1002   - rgd = NULL;
1003   -
1004   - if (remove)
1005   - list_del(&cur_rgd->rd_recent);
1006   -
1007   - goto out;
1008   - }
  956 + head = &sdp->sd_rindex_mru_list;
  957 + if (unlikely(cur_rgd->rd_list_mru.next == head)) {
  958 + spin_unlock(&sdp->sd_rindex_spin);
  959 + return NULL;
1009 960 }
1010   -
1011   - rgd = NULL;
1012   - if (!list_empty(head))
1013   - rgd = list_entry(head->next, struct gfs2_rgrpd, rd_recent);
1014   -
1015   -out:
  961 + rgd = list_entry(cur_rgd->rd_list_mru.next, struct gfs2_rgrpd, rd_list_mru);
1016 962 spin_unlock(&sdp->sd_rindex_spin);
1017 963 return rgd;
1018 964 }
1019 965  
1020 966 /**
1021   - * recent_rgrp_add - add an RG to tail of "recent" list
1022   - * @new_rgd: The rgrp to add
1023   - *
1024   - */
1025   -
1026   -static void recent_rgrp_add(struct gfs2_rgrpd *new_rgd)
1027   -{
1028   - struct gfs2_sbd *sdp = new_rgd->rd_sbd;
1029   - struct gfs2_rgrpd *rgd;
1030   - unsigned int count = 0;
1031   - unsigned int max = sdp->sd_rgrps / gfs2_jindex_size(sdp);
1032   -
1033   - spin_lock(&sdp->sd_rindex_spin);
1034   -
1035   - list_for_each_entry(rgd, &sdp->sd_rindex_recent_list, rd_recent) {
1036   - if (rgd == new_rgd)
1037   - goto out;
1038   -
1039   - if (++count >= max)
1040   - goto out;
1041   - }
1042   - list_add_tail(&new_rgd->rd_recent, &sdp->sd_rindex_recent_list);
1043   -
1044   -out:
1045   - spin_unlock(&sdp->sd_rindex_spin);
1046   -}
1047   -
1048   -/**
1049 967 * forward_rgrp_get - get an rgrp to try next from full list
1050 968 * @sdp: The GFS2 superblock
1051 969 *
1052 970  
... ... @@ -1112,10 +1030,8 @@
1112 1030 int loops = 0;
1113 1031 int error, rg_locked;
1114 1032  
1115   - /* Try recently successful rgrps */
  1033 + rgd = gfs2_blk2rgrpd(sdp, ip->i_goal);
1116 1034  
1117   - rgd = recent_rgrp_first(sdp, ip->i_goal);
1118   -
1119 1035 while (rgd) {
1120 1036 rg_locked = 0;
1121 1037  
1122 1038  
... ... @@ -1136,11 +1052,9 @@
1136 1052 gfs2_glock_dq_uninit(&al->al_rgd_gh);
1137 1053 if (inode)
1138 1054 return inode;
1139   - rgd = recent_rgrp_next(rgd, 1);
1140   - break;
1141   -
  1055 + /* fall through */
1142 1056 case GLR_TRYFAILED:
1143   - rgd = recent_rgrp_next(rgd, 0);
  1057 + rgd = recent_rgrp_next(rgd);
1144 1058 break;
1145 1059  
1146 1060 default:
... ... @@ -1199,7 +1113,9 @@
1199 1113  
1200 1114 out:
1201 1115 if (begin) {
1202   - recent_rgrp_add(rgd);
  1116 + spin_lock(&sdp->sd_rindex_spin);
  1117 + list_move(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list);
  1118 + spin_unlock(&sdp->sd_rindex_spin);
1203 1119 rgd = gfs2_rgrpd_get_next(rgd);
1204 1120 if (!rgd)
1205 1121 rgd = gfs2_rgrpd_get_first(sdp);