diff --git a/security/integrity/digest_cache/internal.h b/security/integrity/digest_cache/internal.h
index e8a13afaf2fc..54e118a2ef79 100644
--- a/security/integrity/digest_cache/internal.h
+++ b/security/integrity/digest_cache/internal.h
@@ -13,11 +13,17 @@
 #include <linux/lsm_hooks.h>
 #include <linux/digest_cache.h>
 
+/* Digest cache bits in flags. */
+#define INIT_IN_PROGRESS	0	/* Digest cache being initialized. */
+#define INIT_STARTED		1	/* Digest cache init started. */
+#define INVALID			2	/* Digest cache marked as invalid. */
+
 /**
  * struct digest_cache - Digest cache
  * @ref_count: Number of references to the digest cache
  * @path_str: Path of the digest list the digest cache was created from
  * @flags: Control flags
+ * @digest_list_path: Path structure of the digest list
  *
  * This structure represents a cache of digests extracted from a digest list.
  */
@@ -25,6 +31,7 @@ struct digest_cache {
 	atomic_t ref_count;
 	char *path_str;
 	unsigned long flags;
+	struct path digest_list_path;
 };
 
 /**
@@ -84,6 +91,8 @@ digest_cache_unref(struct digest_cache *digest_cache)
 struct digest_cache *digest_cache_create(struct dentry *dentry,
 					 struct path *digest_list_path,
 					 char *path_str, char *filename);
+struct digest_cache *digest_cache_init(struct dentry *dentry,
+				       struct digest_cache *digest_cache);
 int __init digest_cache_do_init(const struct lsm_id *lsm_id,
 				loff_t inode_offset);
 
diff --git a/security/integrity/digest_cache/main.c b/security/integrity/digest_cache/main.c
index 60030df04a4d..188f1dcc880e 100644
--- a/security/integrity/digest_cache/main.c
+++ b/security/integrity/digest_cache/main.c
@@ -154,6 +154,14 @@ struct digest_cache *digest_cache_create(struct dentry *dentry,
 
 	/* Increment ref. count for reference returned to the caller. */
 	digest_cache = digest_cache_ref(dig_sec->dig_owner);
+
+	/* Make other digest cache requestors wait until creation complete. */
+	set_bit(INIT_IN_PROGRESS, &digest_cache->flags);
+
+	/* Get the digest list path for initialization. */
+	digest_cache->digest_list_path.dentry = digest_list_path->dentry;
+	digest_cache->digest_list_path.mnt = digest_list_path->mnt;
+	path_get(&digest_cache->digest_list_path);
 	mutex_unlock(&dig_sec->dig_owner_mutex);
 out:
 	if (digest_list_path == &file_path)
@@ -226,6 +234,45 @@ static struct digest_cache *digest_cache_new(struct dentry *dentry)
 	return digest_cache;
 }
 
+/**
+ * digest_cache_init - Initialize a digest cache
+ * @dentry: Dentry of the inode for which the digest cache will be used
+ * @digest_cache: Digest cache to initialize
+ *
+ * This function checks if the INIT_STARTED digest cache flag is set. If it is,
+ * it waits until the caller that saw INIT_STARTED unset completes the
+ * initialization.
+ *
+ * Otherwise, it sets INIT_STARTED (atomically), performs the initialization,
+ * clears the INIT_IN_PROGRESS digest cache flag, and wakes up the other
+ * callers.
+ *
+ * Return: A valid and initialized digest cache.
+ */
+struct digest_cache *digest_cache_init(struct dentry *dentry,
+				       struct digest_cache *digest_cache)
+{
+	/* Wait for digest cache initialization. */
+	if (test_and_set_bit(INIT_STARTED, &digest_cache->flags)) {
+		wait_on_bit(&digest_cache->flags, INIT_IN_PROGRESS,
+			    TASK_UNINTERRUPTIBLE);
+		goto out;
+	}
+
+	path_put(&digest_cache->digest_list_path);
+	/* Notify initialization complete. */
+	clear_and_wake_up_bit(INIT_IN_PROGRESS, &digest_cache->flags);
+out:
+	if (test_bit(INVALID, &digest_cache->flags)) {
+		pr_debug("Digest cache %s is invalid, don't return it\n",
+			 digest_cache->path_str);
+		digest_cache_put(digest_cache);
+		digest_cache = NULL;
+	}
+
+	return digest_cache;
+}
+
 /**
  * digest_cache_get - Get a digest cache for a given inode
  * @dentry: Dentry of the inode for which the digest cache will be used
@@ -268,6 +315,10 @@ struct digest_cache *digest_cache_get(struct dentry *dentry)
 
 	mutex_unlock(&dig_sec->dig_user_mutex);
 
+	if (digest_cache)
+		/* This must be always executed, or path ref. is not released.*/
+		digest_cache = digest_cache_init(dentry, digest_cache);
+
 	return digest_cache;
 }
 EXPORT_SYMBOL_GPL(digest_cache_get);
