diff options
Diffstat (limited to 'fs/gfs2/glock.c')
-rw-r--r-- | fs/gfs2/glock.c | 248 |
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 | ||
63 | static DECLARE_RWSEM(gfs2_umount_flush_sem); | 63 | static DECLARE_RWSEM(gfs2_umount_flush_sem); |
64 | static struct dentry *gfs2_root; | 64 | static struct dentry *gfs2_root; |
65 | static struct task_struct *scand_process; | ||
66 | static unsigned int scand_secs = 5; | ||
67 | static struct workqueue_struct *glock_workqueue; | 65 | static struct workqueue_struct *glock_workqueue; |
66 | static LIST_HEAD(lru_list); | ||
67 | static atomic_t lru_count = ATOMIC_INIT(0); | ||
68 | static 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 | |||
184 | static 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); | ||
199 | out: | 225 | out: |
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 | ||
839 | static void handle_callback(struct gfs2_glock *gl, unsigned int state, | 865 | static 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 | ||
1360 | static int demote_ok(struct gfs2_glock *gl) | 1383 | static 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); | |
1379 | void 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 | ||
1404 | void gfs2_reclaim_glock(struct gfs2_sbd *sdp) | 1397 | static 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); | 1451 | out: |
1452 | return (atomic_read(&lru_count) / 100) * sysctl_vfs_cache_pressure; | ||
1432 | } | 1453 | } |
1433 | 1454 | ||
1455 | static 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 | |||
1484 | static 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 | ||
1504 | static void clear_glock(struct gfs2_glock *gl) | 1510 | static 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 | |||
1787 | static 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 | ||
1808 | int __init gfs2_glock_init(void) | 1777 | int __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 | ||
1833 | void gfs2_glock_exit(void) | 1798 | void 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 | ||
1839 | module_param(scand_secs, uint, S_IRUGO|S_IWUSR); | ||
1840 | MODULE_PARM_DESC(scand_secs, "The number of seconds between scand runs"); | ||
1841 | |||
1842 | static int gfs2_glock_iter_next(struct gfs2_glock_iter *gi) | 1804 | static int gfs2_glock_iter_next(struct gfs2_glock_iter *gi) |
1843 | { | 1805 | { |
1844 | struct gfs2_glock *gl; | 1806 | struct gfs2_glock *gl; |