Merge tag 'drm-next-2022-08-12-1' of git://anongit.freedesktop.org/drm/drm
[linux-2.6-microblaze.git] / fs / gfs2 / glock.c
index 27b5190..41b6c89 100644 (file)
@@ -405,10 +405,13 @@ static void do_error(struct gfs2_glock *gl, const int ret)
 /**
  * demote_incompat_holders - demote incompatible demoteable holders
  * @gl: the glock we want to promote
- * @new_gh: the new holder to be promoted
+ * @current_gh: the newly promoted holder
+ *
+ * We're passing the newly promoted holder in @current_gh, but actually, any of
+ * the strong holders would do.
  */
 static void demote_incompat_holders(struct gfs2_glock *gl,
-                                   struct gfs2_holder *new_gh)
+                                   struct gfs2_holder *current_gh)
 {
        struct gfs2_holder *gh, *tmp;
 
@@ -424,8 +427,10 @@ static void demote_incompat_holders(struct gfs2_glock *gl,
                 */
                if (!test_bit(HIF_HOLDER, &gh->gh_iflags))
                        return;
+               if (gh == current_gh)
+                       continue;
                if (test_bit(HIF_MAY_DEMOTE, &gh->gh_iflags) &&
-                   !may_grant(gl, new_gh, gh)) {
+                   !may_grant(gl, current_gh, gh)) {
                        /*
                         * We should not recurse into do_promote because
                         * __gfs2_glock_dq only calls handle_callback,
@@ -529,32 +534,33 @@ done:
 
 static int do_promote(struct gfs2_glock *gl)
 {
-       struct gfs2_holder *gh, *tmp, *current_gh;
+       struct gfs2_holder *gh, *current_gh;
        bool incompat_holders_demoted = false;
 
        current_gh = find_first_strong_holder(gl);
-       list_for_each_entry_safe(gh, tmp, &gl->gl_holders, gh_list) {
+       list_for_each_entry(gh, &gl->gl_holders, gh_list) {
                if (test_bit(HIF_HOLDER, &gh->gh_iflags))
                        continue;
                if (!may_grant(gl, current_gh, gh)) {
                        /*
-                        * If we get here, it means we may not grant this holder for
-                        * some reason. If this holder is the head of the list, it
-                        * means we have a blocked holder at the head, so return 1.
+                        * If we get here, it means we may not grant this
+                        * holder for some reason. If this holder is at the
+                        * head of the list, it means we have a blocked holder
+                        * at the head, so return 1.
                         */
                        if (list_is_first(&gh->gh_list, &gl->gl_holders))
                                return 1;
                        do_error(gl, 0);
                        break;
                }
+               set_bit(HIF_HOLDER, &gh->gh_iflags);
+               trace_gfs2_promote(gh);
+               gfs2_holder_wake(gh);
                if (!incompat_holders_demoted) {
+                       current_gh = gh;
                        demote_incompat_holders(gl, current_gh);
                        incompat_holders_demoted = true;
-                       current_gh = gh;
                }
-               set_bit(HIF_HOLDER, &gh->gh_iflags);
-               trace_gfs2_promote(gh);
-               gfs2_holder_wake(gh);
        }
        return 0;
 }
@@ -1745,7 +1751,7 @@ static int glock_compare(const void *arg_a, const void *arg_b)
 }
 
 /**
- * nq_m_sync - synchonously acquire more than one glock in deadlock free order
+ * nq_m_sync - synchronously acquire more than one glock in deadlock free order
  * @num_gh: the number of structures
  * @ghs: an array of struct gfs2_holder structures
  * @p: placeholder for the holder structure to pass back
@@ -1766,8 +1772,6 @@ static int nq_m_sync(unsigned int num_gh, struct gfs2_holder *ghs,
        sort(p, num_gh, sizeof(struct gfs2_holder *), glock_compare, NULL);
 
        for (x = 0; x < num_gh; x++) {
-               p[x]->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC);
-
                error = gfs2_glock_nq(p[x]);
                if (error) {
                        while (x--)
@@ -1784,7 +1788,6 @@ static int nq_m_sync(unsigned int num_gh, struct gfs2_holder *ghs,
  * @num_gh: the number of structures
  * @ghs: an array of struct gfs2_holder structures
  *
- *
  * Returns: 0 on success (all glocks acquired),
  *          errno on failure (no glocks acquired)
  */
@@ -1799,7 +1802,6 @@ int gfs2_glock_nq_m(unsigned int num_gh, struct gfs2_holder *ghs)
        case 0:
                return 0;
        case 1:
-               ghs->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC);
                return gfs2_glock_nq(ghs);
        default:
                if (num_gh <= 4)
@@ -2485,7 +2487,7 @@ int __init gfs2_glock_init(void)
                return -ENOMEM;
        }
 
-       ret = register_shrinker(&glock_shrinker);
+       ret = register_shrinker(&glock_shrinker, "gfs2-glock");
        if (ret) {
                destroy_workqueue(gfs2_delete_workqueue);
                destroy_workqueue(glock_workqueue);