|
@@ -37,6 +37,7 @@
|
|
|
#include <linux/swapfile.h>
|
|
|
#include <linux/export.h>
|
|
|
#include <linux/swap_slots.h>
|
|
|
+#include <linux/sort.h>
|
|
|
|
|
|
#include <asm/pgtable.h>
|
|
|
#include <asm/tlbflush.h>
|
|
@@ -1198,6 +1199,13 @@ void put_swap_page(struct page *page, swp_entry_t entry)
|
|
|
swapcache_free_cluster(entry);
|
|
|
}
|
|
|
|
|
|
+static int swp_entry_cmp(const void *ent1, const void *ent2)
|
|
|
+{
|
|
|
+ const swp_entry_t *e1 = ent1, *e2 = ent2;
|
|
|
+
|
|
|
+ return (int)swp_type(*e1) - (int)swp_type(*e2);
|
|
|
+}
|
|
|
+
|
|
|
void swapcache_free_entries(swp_entry_t *entries, int n)
|
|
|
{
|
|
|
struct swap_info_struct *p, *prev;
|
|
@@ -1208,6 +1216,14 @@ void swapcache_free_entries(swp_entry_t *entries, int n)
|
|
|
|
|
|
prev = NULL;
|
|
|
p = NULL;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Sort swap entries by swap device, so each lock is only taken once.
|
|
|
+ * nr_swapfiles isn't absolutely correct, but the overhead of sort() is
|
|
|
+ * so low that it isn't necessary to optimize further.
|
|
|
+ */
|
|
|
+ if (nr_swapfiles > 1)
|
|
|
+ sort(entries, n, sizeof(entries[0]), swp_entry_cmp, NULL);
|
|
|
for (i = 0; i < n; ++i) {
|
|
|
p = swap_info_get_cont(entries[i], prev);
|
|
|
if (p)
|