aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/glock.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2008-11-20 08:39:47 -0500
committerSteven Whitehouse <swhiteho@redhat.com>2009-01-05 02:39:09 -0500
commit97cc1025b1a91c52e84f12478dcf0f853abc6564 (patch)
treecd71419049aeb13eea7012889d0ee0c715394e4d /fs/gfs2/glock.c
parent9ac1b4d9b6f885ccd7d8f56bceb609003a920ff7 (diff)
GFS2: Kill two daemons with one patch
This patch removes the two daemons, gfs2_scand and gfs2_glockd and replaces them with a shrinker which is called from the VM. The net result is that GFS2 responds better when there is memory pressure, since it shrinks the glock cache at the same rate as the VFS shrinks the dcache and icache. There are no longer any time based criteria for shrinking glocks, they are kept until such time as the VM asks for more memory and then we demote just as many glocks as required. There are potential future changes to this code, including the possibility of sorting the glocks which are to be written back into inode number order, to get a better I/O ordering. It would be very useful to have an elevator based workqueue implementation for this, as that would automatically deal with the read I/O cases at the same time. This patch is my answer to Andrew Morton's remark, made during the initial review of GFS2, asking why GFS2 needs so many kernel threads, the answer being that it doesn't :-) This patch is a net loss of about 200 lines of code. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/glock.c')
-rw-r--r--fs/gfs2/glock.c248
1 files changed, 105 insertions, 143 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 4ddf3bd55dda..07ffc8123d74 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -62,9 +62,10 @@ static void do_xmote(struct gfs2_glock *gl, struct gfs2_holder *gh, unsigned int
62 62
63static DECLARE_RWSEM(gfs2_umount_flush_sem); 63static DECLARE_RWSEM(gfs2_umount_flush_sem);
64static struct dentry *gfs2_root; 64static struct dentry *gfs2_root;
65static struct task_struct *scand_process;
66static unsigned int scand_secs = 5;
67static struct workqueue_struct *glock_workqueue; 65static struct workqueue_struct *glock_workqueue;
66static LIST_HEAD(lru_list);
67static atomic_t lru_count = ATOMIC_INIT(0);
68static spinlock_t lru_lock = SPIN_LOCK_UNLOCKED;
68 69
69#define GFS2_GL_HASH_SHIFT 15 70#define GFS2_GL_HASH_SHIFT 15
70#define GFS2_GL_HASH_SIZE (1 << GFS2_GL_HASH_SHIFT) 71#define GFS2_GL_HASH_SIZE (1 << GFS2_GL_HASH_SHIFT)
@@ -175,6 +176,22 @@ static void gfs2_glock_hold(struct gfs2_glock *gl)
175} 176}
176 177
177/** 178/**
179 * gfs2_glock_schedule_for_reclaim - Add a glock to the reclaim list
180 * @gl: the glock
181 *
182 */
183
184static void gfs2_glock_schedule_for_reclaim(struct gfs2_glock *gl)
185{
186 spin_lock(&lru_lock);
187 if (list_empty(&gl->gl_lru) && gl->gl_state != LM_ST_UNLOCKED) {
188 list_add_tail(&gl->gl_lru, &lru_list);
189 atomic_inc(&lru_count);
190 }
191 spin_unlock(&lru_lock);
192}
193
194/**
178 * gfs2_glock_put() - Decrement reference count on glock 195 * gfs2_glock_put() - Decrement reference count on glock
179 * @gl: The glock to put 196 * @gl: The glock to put
180 * 197 *
@@ -188,14 +205,23 @@ int gfs2_glock_put(struct gfs2_glock *gl)
188 if (atomic_dec_and_test(&gl->gl_ref)) { 205 if (atomic_dec_and_test(&gl->gl_ref)) {
189 hlist_del(&gl->gl_list); 206 hlist_del(&gl->gl_list);
190 write_unlock(gl_lock_addr(gl->gl_hash)); 207 write_unlock(gl_lock_addr(gl->gl_hash));
208 spin_lock(&lru_lock);
209 if (!list_empty(&gl->gl_lru)) {
210 list_del_init(&gl->gl_lru);
211 atomic_dec(&lru_count);
212 }
213 spin_unlock(&lru_lock);
191 GLOCK_BUG_ON(gl, gl->gl_state != LM_ST_UNLOCKED); 214 GLOCK_BUG_ON(gl, gl->gl_state != LM_ST_UNLOCKED);
192 GLOCK_BUG_ON(gl, !list_empty(&gl->gl_reclaim)); 215 GLOCK_BUG_ON(gl, !list_empty(&gl->gl_lru));
193 GLOCK_BUG_ON(gl, !list_empty(&gl->gl_holders)); 216 GLOCK_BUG_ON(gl, !list_empty(&gl->gl_holders));
194 glock_free(gl); 217 glock_free(gl);
195 rv = 1; 218 rv = 1;
196 goto out; 219 goto out;
197 } 220 }
198 write_unlock(gl_lock_addr(gl->gl_hash)); 221 write_unlock(gl_lock_addr(gl->gl_hash));
222 /* 1 for being hashed, 1 for having state != LM_ST_UNLOCKED */
223 if (atomic_read(&gl->gl_ref) == 2)
224 gfs2_glock_schedule_for_reclaim(gl);
199out: 225out:
200 return rv; 226 return rv;
201} 227}
@@ -837,7 +863,7 @@ static void wait_on_demote(struct gfs2_glock *gl)
837 */ 863 */
838 864
839static void handle_callback(struct gfs2_glock *gl, unsigned int state, 865static void handle_callback(struct gfs2_glock *gl, unsigned int state,
840 int remote, unsigned long delay) 866 unsigned long delay)
841{ 867{
842 int bit = delay ? GLF_PENDING_DEMOTE : GLF_DEMOTE; 868 int bit = delay ? GLF_PENDING_DEMOTE : GLF_DEMOTE;
843 869
@@ -845,9 +871,6 @@ static void handle_callback(struct gfs2_glock *gl, unsigned int state,
845 if (gl->gl_demote_state == LM_ST_EXCLUSIVE) { 871 if (gl->gl_demote_state == LM_ST_EXCLUSIVE) {
846 gl->gl_demote_state = state; 872 gl->gl_demote_state = state;
847 gl->gl_demote_time = jiffies; 873 gl->gl_demote_time = jiffies;
848 if (remote && gl->gl_ops->go_type == LM_TYPE_IOPEN &&
849 gl->gl_object)
850 gfs2_glock_schedule_for_reclaim(gl);
851 } else if (gl->gl_demote_state != LM_ST_UNLOCKED && 874 } else if (gl->gl_demote_state != LM_ST_UNLOCKED &&
852 gl->gl_demote_state != state) { 875 gl->gl_demote_state != state) {
853 gl->gl_demote_state = LM_ST_UNLOCKED; 876 gl->gl_demote_state = LM_ST_UNLOCKED;
@@ -1017,7 +1040,7 @@ void gfs2_glock_dq(struct gfs2_holder *gh)
1017 1040
1018 spin_lock(&gl->gl_spin); 1041 spin_lock(&gl->gl_spin);
1019 if (gh->gh_flags & GL_NOCACHE) 1042 if (gh->gh_flags & GL_NOCACHE)
1020 handle_callback(gl, LM_ST_UNLOCKED, 0, 0); 1043 handle_callback(gl, LM_ST_UNLOCKED, 0);
1021 1044
1022 list_del_init(&gh->gh_list); 1045 list_del_init(&gh->gh_list);
1023 if (find_first_holder(gl) == NULL) { 1046 if (find_first_holder(gl) == NULL) {
@@ -1288,7 +1311,7 @@ static void blocking_cb(struct gfs2_sbd *sdp, struct lm_lockname *name,
1288 delay = gl->gl_ops->go_min_hold_time; 1311 delay = gl->gl_ops->go_min_hold_time;
1289 1312
1290 spin_lock(&gl->gl_spin); 1313 spin_lock(&gl->gl_spin);
1291 handle_callback(gl, state, 1, delay); 1314 handle_callback(gl, state, delay);
1292 spin_unlock(&gl->gl_spin); 1315 spin_unlock(&gl->gl_spin);
1293 if (queue_delayed_work(glock_workqueue, &gl->gl_work, delay) == 0) 1316 if (queue_delayed_work(glock_workqueue, &gl->gl_work, delay) == 0)
1294 gfs2_glock_put(gl); 1317 gfs2_glock_put(gl);
@@ -1357,80 +1380,83 @@ void gfs2_glock_cb(void *cb_data, unsigned int type, void *data)
1357 * Returns: 1 if it's ok 1380 * Returns: 1 if it's ok
1358 */ 1381 */
1359 1382
1360static int demote_ok(struct gfs2_glock *gl) 1383static int demote_ok(const struct gfs2_glock *gl)
1361{ 1384{
1362 const struct gfs2_glock_operations *glops = gl->gl_ops; 1385 const struct gfs2_glock_operations *glops = gl->gl_ops;
1363 int demote = 1;
1364
1365 if (test_bit(GLF_STICKY, &gl->gl_flags))
1366 demote = 0;
1367 else if (glops->go_demote_ok)
1368 demote = glops->go_demote_ok(gl);
1369
1370 return demote;
1371}
1372 1386
1373/** 1387 if (gl->gl_state == LM_ST_UNLOCKED)
1374 * gfs2_glock_schedule_for_reclaim - Add a glock to the reclaim list 1388 return 0;
1375 * @gl: the glock 1389 if (!list_empty(&gl->gl_holders))
1376 * 1390 return 0;
1377 */ 1391 if (glops->go_demote_ok)
1378 1392 return glops->go_demote_ok(gl);
1379void gfs2_glock_schedule_for_reclaim(struct gfs2_glock *gl) 1393 return 1;
1380{
1381 struct gfs2_sbd *sdp = gl->gl_sbd;
1382
1383 spin_lock(&sdp->sd_reclaim_lock);
1384 if (list_empty(&gl->gl_reclaim)) {
1385 gfs2_glock_hold(gl);
1386 list_add(&gl->gl_reclaim, &sdp->sd_reclaim_list);
1387 atomic_inc(&sdp->sd_reclaim_count);
1388 spin_unlock(&sdp->sd_reclaim_lock);
1389 wake_up(&sdp->sd_reclaim_wq);
1390 } else
1391 spin_unlock(&sdp->sd_reclaim_lock);
1392} 1394}
1393 1395
1394/**
1395 * gfs2_reclaim_glock - process the next glock on the filesystem's reclaim list
1396 * @sdp: the filesystem
1397 *
1398 * Called from gfs2_glockd() glock reclaim daemon, or when promoting a
1399 * different glock and we notice that there are a lot of glocks in the
1400 * reclaim list.
1401 *
1402 */
1403 1396
1404void gfs2_reclaim_glock(struct gfs2_sbd *sdp) 1397static int gfs2_shrink_glock_memory(int nr, gfp_t gfp_mask)
1405{ 1398{
1406 struct gfs2_glock *gl; 1399 struct gfs2_glock *gl;
1407 int done_callback = 0; 1400 int may_demote;
1401 int nr_skipped = 0;
1402 int got_ref = 0;
1403 LIST_HEAD(skipped);
1408 1404
1409 spin_lock(&sdp->sd_reclaim_lock); 1405 if (nr == 0)
1410 if (list_empty(&sdp->sd_reclaim_list)) { 1406 goto out;
1411 spin_unlock(&sdp->sd_reclaim_lock);
1412 return;
1413 }
1414 gl = list_entry(sdp->sd_reclaim_list.next,
1415 struct gfs2_glock, gl_reclaim);
1416 list_del_init(&gl->gl_reclaim);
1417 spin_unlock(&sdp->sd_reclaim_lock);
1418 1407
1419 atomic_dec(&sdp->sd_reclaim_count); 1408 if (!(gfp_mask & __GFP_FS))
1420 atomic_inc(&sdp->sd_reclaimed); 1409 return -1;
1421 1410
1422 spin_lock(&gl->gl_spin); 1411 spin_lock(&lru_lock);
1423 if (find_first_holder(gl) == NULL && 1412 while(nr && !list_empty(&lru_list)) {
1424 gl->gl_state != LM_ST_UNLOCKED && demote_ok(gl)) { 1413 gl = list_entry(lru_list.next, struct gfs2_glock, gl_lru);
1425 handle_callback(gl, LM_ST_UNLOCKED, 0, 0); 1414 list_del_init(&gl->gl_lru);
1426 done_callback = 1; 1415 atomic_dec(&lru_count);
1416
1417 /* Test for being demotable */
1418 if (!test_and_set_bit(GLF_LOCK, &gl->gl_flags)) {
1419 gfs2_glock_hold(gl);
1420 got_ref = 1;
1421 spin_unlock(&lru_lock);
1422 spin_lock(&gl->gl_spin);
1423 may_demote = demote_ok(gl);
1424 spin_unlock(&gl->gl_spin);
1425 clear_bit(GLF_LOCK, &gl->gl_flags);
1426 if (may_demote) {
1427 handle_callback(gl, LM_ST_UNLOCKED, 0);
1428 nr--;
1429 if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0)
1430 gfs2_glock_put(gl);
1431 }
1432 spin_lock(&lru_lock);
1433 if (may_demote)
1434 continue;
1435 }
1436 if (list_empty(&gl->gl_lru) &&
1437 (atomic_read(&gl->gl_ref) <= (2 + got_ref))) {
1438 nr_skipped++;
1439 list_add(&gl->gl_lru, &skipped);
1440 }
1441 if (got_ref) {
1442 spin_unlock(&lru_lock);
1443 gfs2_glock_put(gl);
1444 spin_lock(&lru_lock);
1445 got_ref = 0;
1446 }
1427 } 1447 }
1428 spin_unlock(&gl->gl_spin); 1448 list_splice(&skipped, &lru_list);
1429 if (!done_callback || 1449 atomic_add(nr_skipped, &lru_count);
1430 queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0) 1450 spin_unlock(&lru_lock);
1431 gfs2_glock_put(gl); 1451out:
1452 return (atomic_read(&lru_count) / 100) * sysctl_vfs_cache_pressure;
1432} 1453}
1433 1454
1455static struct shrinker glock_shrinker = {
1456 .shrink = gfs2_shrink_glock_memory,
1457 .seeks = DEFAULT_SEEKS,
1458};
1459
1434/** 1460/**
1435 * examine_bucket - Call a function for glock in a hash bucket 1461 * examine_bucket - Call a function for glock in a hash bucket
1436 * @examiner: the function 1462 * @examiner: the function
@@ -1476,26 +1502,6 @@ out:
1476} 1502}
1477 1503
1478/** 1504/**
1479 * scan_glock - look at a glock and see if we can reclaim it
1480 * @gl: the glock to look at
1481 *
1482 */
1483
1484static void scan_glock(struct gfs2_glock *gl)
1485{
1486 if (gl->gl_ops == &gfs2_inode_glops && gl->gl_object)
1487 return;
1488 if (test_bit(GLF_LOCK, &gl->gl_flags))
1489 return;
1490
1491 spin_lock(&gl->gl_spin);
1492 if (find_first_holder(gl) == NULL &&
1493 gl->gl_state != LM_ST_UNLOCKED && demote_ok(gl))
1494 gfs2_glock_schedule_for_reclaim(gl);
1495 spin_unlock(&gl->gl_spin);
1496}
1497
1498/**
1499 * clear_glock - look at a glock and see if we can free it from glock cache 1505 * clear_glock - look at a glock and see if we can free it from glock cache
1500 * @gl: the glock to look at 1506 * @gl: the glock to look at
1501 * 1507 *
@@ -1503,23 +1509,16 @@ static void scan_glock(struct gfs2_glock *gl)
1503 1509
1504static void clear_glock(struct gfs2_glock *gl) 1510static void clear_glock(struct gfs2_glock *gl)
1505{ 1511{
1506 struct gfs2_sbd *sdp = gl->gl_sbd; 1512 spin_lock(&lru_lock);
1507 int released; 1513 if (!list_empty(&gl->gl_lru)) {
1508 1514 list_del_init(&gl->gl_lru);
1509 spin_lock(&sdp->sd_reclaim_lock); 1515 atomic_dec(&lru_count);
1510 if (!list_empty(&gl->gl_reclaim)) {
1511 list_del_init(&gl->gl_reclaim);
1512 atomic_dec(&sdp->sd_reclaim_count);
1513 spin_unlock(&sdp->sd_reclaim_lock);
1514 released = gfs2_glock_put(gl);
1515 gfs2_assert(sdp, !released);
1516 } else {
1517 spin_unlock(&sdp->sd_reclaim_lock);
1518 } 1516 }
1517 spin_unlock(&lru_lock);
1519 1518
1520 spin_lock(&gl->gl_spin); 1519 spin_lock(&gl->gl_spin);
1521 if (find_first_holder(gl) == NULL && gl->gl_state != LM_ST_UNLOCKED) 1520 if (find_first_holder(gl) == NULL && gl->gl_state != LM_ST_UNLOCKED)
1522 handle_callback(gl, LM_ST_UNLOCKED, 0, 0); 1521 handle_callback(gl, LM_ST_UNLOCKED, 0);
1523 spin_unlock(&gl->gl_spin); 1522 spin_unlock(&gl->gl_spin);
1524 gfs2_glock_hold(gl); 1523 gfs2_glock_hold(gl);
1525 if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0) 1524 if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0)
@@ -1656,8 +1655,6 @@ static const char *gflags2str(char *buf, const unsigned long *gflags)
1656 char *p = buf; 1655 char *p = buf;
1657 if (test_bit(GLF_LOCK, gflags)) 1656 if (test_bit(GLF_LOCK, gflags))
1658 *p++ = 'l'; 1657 *p++ = 'l';
1659 if (test_bit(GLF_STICKY, gflags))
1660 *p++ = 's';
1661 if (test_bit(GLF_DEMOTE, gflags)) 1658 if (test_bit(GLF_DEMOTE, gflags))
1662 *p++ = 'D'; 1659 *p++ = 'D';
1663 if (test_bit(GLF_PENDING_DEMOTE, gflags)) 1660 if (test_bit(GLF_PENDING_DEMOTE, gflags))
@@ -1776,34 +1773,6 @@ static int gfs2_dump_lockstate(struct gfs2_sbd *sdp)
1776 return error; 1773 return error;
1777} 1774}
1778 1775
1779/**
1780 * gfs2_scand - Look for cached glocks and inodes to toss from memory
1781 * @sdp: Pointer to GFS2 superblock
1782 *
1783 * One of these daemons runs, finding candidates to add to sd_reclaim_list.
1784 * See gfs2_glockd()
1785 */
1786
1787static int gfs2_scand(void *data)
1788{
1789 unsigned x;
1790 unsigned delay;
1791
1792 while (!kthread_should_stop()) {
1793 for (x = 0; x < GFS2_GL_HASH_SIZE; x++)
1794 examine_bucket(scan_glock, NULL, x);
1795 if (freezing(current))
1796 refrigerator();
1797 delay = scand_secs;
1798 if (delay < 1)
1799 delay = 1;
1800 schedule_timeout_interruptible(delay * HZ);
1801 }
1802
1803 return 0;
1804}
1805
1806
1807 1776
1808int __init gfs2_glock_init(void) 1777int __init gfs2_glock_init(void)
1809{ 1778{
@@ -1817,28 +1786,21 @@ int __init gfs2_glock_init(void)
1817 } 1786 }
1818#endif 1787#endif
1819 1788
1820 scand_process = kthread_run(gfs2_scand, NULL, "gfs2_scand");
1821 if (IS_ERR(scand_process))
1822 return PTR_ERR(scand_process);
1823
1824 glock_workqueue = create_workqueue("glock_workqueue"); 1789 glock_workqueue = create_workqueue("glock_workqueue");
1825 if (IS_ERR(glock_workqueue)) { 1790 if (IS_ERR(glock_workqueue))
1826 kthread_stop(scand_process);
1827 return PTR_ERR(glock_workqueue); 1791 return PTR_ERR(glock_workqueue);
1828 } 1792
1793 register_shrinker(&glock_shrinker);
1829 1794
1830 return 0; 1795 return 0;
1831} 1796}
1832 1797
1833void gfs2_glock_exit(void) 1798void gfs2_glock_exit(void)
1834{ 1799{
1800 unregister_shrinker(&glock_shrinker);
1835 destroy_workqueue(glock_workqueue); 1801 destroy_workqueue(glock_workqueue);
1836 kthread_stop(scand_process);
1837} 1802}
1838 1803
1839module_param(scand_secs, uint, S_IRUGO|S_IWUSR);
1840MODULE_PARM_DESC(scand_secs, "The number of seconds between scand runs");
1841
1842static int gfs2_glock_iter_next(struct gfs2_glock_iter *gi) 1804static int gfs2_glock_iter_next(struct gfs2_glock_iter *gi)
1843{ 1805{
1844 struct gfs2_glock *gl; 1806 struct gfs2_glock *gl;