Skip to content

Commit b53966f

Browse files
committed
Merge tag 'for-linus-5.10c-rc8-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip
Pull xen fixes from Juergen Gross: "A short series fixing a regression introduced in 5.9 for running as Xen dom0 on a system with NVMe backed storage" * tag 'for-linus-5.10c-rc8-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip: xen: don't use page->lru for ZONE_DEVICE memory xen: add helpers for caching grant mapping pages
2 parents b01dedd + ee32f32 commit b53966f

File tree

7 files changed

+182
-137
lines changed

7 files changed

+182
-137
lines changed

drivers/block/xen-blkback/blkback.c

Lines changed: 17 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -132,73 +132,12 @@ module_param(log_stats, int, 0644);
132132

133133
#define BLKBACK_INVALID_HANDLE (~0)
134134

135-
/* Number of free pages to remove on each call to gnttab_free_pages */
136-
#define NUM_BATCH_FREE_PAGES 10
137-
138135
static inline bool persistent_gnt_timeout(struct persistent_gnt *persistent_gnt)
139136
{
140137
return pgrant_timeout && (jiffies - persistent_gnt->last_used >=
141138
HZ * pgrant_timeout);
142139
}
143140

144-
static inline int get_free_page(struct xen_blkif_ring *ring, struct page **page)
145-
{
146-
unsigned long flags;
147-
148-
spin_lock_irqsave(&ring->free_pages_lock, flags);
149-
if (list_empty(&ring->free_pages)) {
150-
BUG_ON(ring->free_pages_num != 0);
151-
spin_unlock_irqrestore(&ring->free_pages_lock, flags);
152-
return gnttab_alloc_pages(1, page);
153-
}
154-
BUG_ON(ring->free_pages_num == 0);
155-
page[0] = list_first_entry(&ring->free_pages, struct page, lru);
156-
list_del(&page[0]->lru);
157-
ring->free_pages_num--;
158-
spin_unlock_irqrestore(&ring->free_pages_lock, flags);
159-
160-
return 0;
161-
}
162-
163-
static inline void put_free_pages(struct xen_blkif_ring *ring, struct page **page,
164-
int num)
165-
{
166-
unsigned long flags;
167-
int i;
168-
169-
spin_lock_irqsave(&ring->free_pages_lock, flags);
170-
for (i = 0; i < num; i++)
171-
list_add(&page[i]->lru, &ring->free_pages);
172-
ring->free_pages_num += num;
173-
spin_unlock_irqrestore(&ring->free_pages_lock, flags);
174-
}
175-
176-
static inline void shrink_free_pagepool(struct xen_blkif_ring *ring, int num)
177-
{
178-
/* Remove requested pages in batches of NUM_BATCH_FREE_PAGES */
179-
struct page *page[NUM_BATCH_FREE_PAGES];
180-
unsigned int num_pages = 0;
181-
unsigned long flags;
182-
183-
spin_lock_irqsave(&ring->free_pages_lock, flags);
184-
while (ring->free_pages_num > num) {
185-
BUG_ON(list_empty(&ring->free_pages));
186-
page[num_pages] = list_first_entry(&ring->free_pages,
187-
struct page, lru);
188-
list_del(&page[num_pages]->lru);
189-
ring->free_pages_num--;
190-
if (++num_pages == NUM_BATCH_FREE_PAGES) {
191-
spin_unlock_irqrestore(&ring->free_pages_lock, flags);
192-
gnttab_free_pages(num_pages, page);
193-
spin_lock_irqsave(&ring->free_pages_lock, flags);
194-
num_pages = 0;
195-
}
196-
}
197-
spin_unlock_irqrestore(&ring->free_pages_lock, flags);
198-
if (num_pages != 0)
199-
gnttab_free_pages(num_pages, page);
200-
}
201-
202141
#define vaddr(page) ((unsigned long)pfn_to_kaddr(page_to_pfn(page)))
203142

204143
static int do_block_io_op(struct xen_blkif_ring *ring, unsigned int *eoi_flags);
@@ -331,7 +270,8 @@ static void free_persistent_gnts(struct xen_blkif_ring *ring, struct rb_root *ro
331270
unmap_data.count = segs_to_unmap;
332271
BUG_ON(gnttab_unmap_refs_sync(&unmap_data));
333272

334-
put_free_pages(ring, pages, segs_to_unmap);
273+
gnttab_page_cache_put(&ring->free_pages, pages,
274+
segs_to_unmap);
335275
segs_to_unmap = 0;
336276
}
337277

@@ -371,15 +311,16 @@ void xen_blkbk_unmap_purged_grants(struct work_struct *work)
371311
if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST) {
372312
unmap_data.count = segs_to_unmap;
373313
BUG_ON(gnttab_unmap_refs_sync(&unmap_data));
374-
put_free_pages(ring, pages, segs_to_unmap);
314+
gnttab_page_cache_put(&ring->free_pages, pages,
315+
segs_to_unmap);
375316
segs_to_unmap = 0;
376317
}
377318
kfree(persistent_gnt);
378319
}
379320
if (segs_to_unmap > 0) {
380321
unmap_data.count = segs_to_unmap;
381322
BUG_ON(gnttab_unmap_refs_sync(&unmap_data));
382-
put_free_pages(ring, pages, segs_to_unmap);
323+
gnttab_page_cache_put(&ring->free_pages, pages, segs_to_unmap);
383324
}
384325
}
385326

@@ -664,9 +605,10 @@ int xen_blkif_schedule(void *arg)
664605

665606
/* Shrink the free pages pool if it is too large. */
666607
if (time_before(jiffies, blkif->buffer_squeeze_end))
667-
shrink_free_pagepool(ring, 0);
608+
gnttab_page_cache_shrink(&ring->free_pages, 0);
668609
else
669-
shrink_free_pagepool(ring, max_buffer_pages);
610+
gnttab_page_cache_shrink(&ring->free_pages,
611+
max_buffer_pages);
670612

671613
if (log_stats && time_after(jiffies, ring->st_print))
672614
print_stats(ring);
@@ -697,7 +639,7 @@ void xen_blkbk_free_caches(struct xen_blkif_ring *ring)
697639
ring->persistent_gnt_c = 0;
698640

699641
/* Since we are shutting down remove all pages from the buffer */
700-
shrink_free_pagepool(ring, 0 /* All */);
642+
gnttab_page_cache_shrink(&ring->free_pages, 0 /* All */);
701643
}
702644

703645
static unsigned int xen_blkbk_unmap_prepare(
@@ -736,7 +678,7 @@ static void xen_blkbk_unmap_and_respond_callback(int result, struct gntab_unmap_
736678
but is this the best way to deal with this? */
737679
BUG_ON(result);
738680

739-
put_free_pages(ring, data->pages, data->count);
681+
gnttab_page_cache_put(&ring->free_pages, data->pages, data->count);
740682
make_response(ring, pending_req->id,
741683
pending_req->operation, pending_req->status);
742684
free_req(ring, pending_req);
@@ -803,7 +745,8 @@ static void xen_blkbk_unmap(struct xen_blkif_ring *ring,
803745
if (invcount) {
804746
ret = gnttab_unmap_refs(unmap, NULL, unmap_pages, invcount);
805747
BUG_ON(ret);
806-
put_free_pages(ring, unmap_pages, invcount);
748+
gnttab_page_cache_put(&ring->free_pages, unmap_pages,
749+
invcount);
807750
}
808751
pages += batch;
809752
num -= batch;
@@ -850,7 +793,8 @@ static int xen_blkbk_map(struct xen_blkif_ring *ring,
850793
pages[i]->page = persistent_gnt->page;
851794
pages[i]->persistent_gnt = persistent_gnt;
852795
} else {
853-
if (get_free_page(ring, &pages[i]->page))
796+
if (gnttab_page_cache_get(&ring->free_pages,
797+
&pages[i]->page))
854798
goto out_of_memory;
855799
addr = vaddr(pages[i]->page);
856800
pages_to_gnt[segs_to_map] = pages[i]->page;
@@ -883,7 +827,8 @@ static int xen_blkbk_map(struct xen_blkif_ring *ring,
883827
BUG_ON(new_map_idx >= segs_to_map);
884828
if (unlikely(map[new_map_idx].status != 0)) {
885829
pr_debug("invalid buffer -- could not remap it\n");
886-
put_free_pages(ring, &pages[seg_idx]->page, 1);
830+
gnttab_page_cache_put(&ring->free_pages,
831+
&pages[seg_idx]->page, 1);
887832
pages[seg_idx]->handle = BLKBACK_INVALID_HANDLE;
888833
ret |= 1;
889834
goto next;
@@ -944,7 +889,7 @@ static int xen_blkbk_map(struct xen_blkif_ring *ring,
944889

945890
out_of_memory:
946891
pr_alert("%s: out of memory\n", __func__);
947-
put_free_pages(ring, pages_to_gnt, segs_to_map);
892+
gnttab_page_cache_put(&ring->free_pages, pages_to_gnt, segs_to_map);
948893
for (i = last_map; i < num; i++)
949894
pages[i]->handle = BLKBACK_INVALID_HANDLE;
950895
return -ENOMEM;

drivers/block/xen-blkback/common.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -288,9 +288,7 @@ struct xen_blkif_ring {
288288
struct work_struct persistent_purge_work;
289289

290290
/* Buffer of free pages to map grant refs. */
291-
spinlock_t free_pages_lock;
292-
int free_pages_num;
293-
struct list_head free_pages;
291+
struct gnttab_page_cache free_pages;
294292

295293
struct work_struct free_work;
296294
/* Thread shutdown wait queue. */

drivers/block/xen-blkback/xenbus.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,7 @@ static int xen_blkif_alloc_rings(struct xen_blkif *blkif)
144144
INIT_LIST_HEAD(&ring->pending_free);
145145
INIT_LIST_HEAD(&ring->persistent_purge_list);
146146
INIT_WORK(&ring->persistent_purge_work, xen_blkbk_unmap_purged_grants);
147-
spin_lock_init(&ring->free_pages_lock);
148-
INIT_LIST_HEAD(&ring->free_pages);
147+
gnttab_page_cache_init(&ring->free_pages);
149148

150149
spin_lock_init(&ring->pending_free_lock);
151150
init_waitqueue_head(&ring->pending_free_wq);
@@ -317,8 +316,7 @@ static int xen_blkif_disconnect(struct xen_blkif *blkif)
317316
BUG_ON(atomic_read(&ring->persistent_gnt_in_use) != 0);
318317
BUG_ON(!list_empty(&ring->persistent_purge_list));
319318
BUG_ON(!RB_EMPTY_ROOT(&ring->persistent_gnts));
320-
BUG_ON(!list_empty(&ring->free_pages));
321-
BUG_ON(ring->free_pages_num != 0);
319+
BUG_ON(ring->free_pages.num_pages != 0);
322320
BUG_ON(ring->persistent_gnt_c != 0);
323321
WARN_ON(i != (XEN_BLKIF_REQS_PER_PAGE * blkif->nr_ring_pages));
324322
ring->active = false;

drivers/xen/grant-table.c

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,129 @@ int gnttab_alloc_pages(int nr_pages, struct page **pages)
813813
}
814814
EXPORT_SYMBOL_GPL(gnttab_alloc_pages);
815815

816+
#ifdef CONFIG_XEN_UNPOPULATED_ALLOC
817+
static inline void cache_init(struct gnttab_page_cache *cache)
818+
{
819+
cache->pages = NULL;
820+
}
821+
822+
static inline bool cache_empty(struct gnttab_page_cache *cache)
823+
{
824+
return !cache->pages;
825+
}
826+
827+
static inline struct page *cache_deq(struct gnttab_page_cache *cache)
828+
{
829+
struct page *page;
830+
831+
page = cache->pages;
832+
cache->pages = page->zone_device_data;
833+
834+
return page;
835+
}
836+
837+
static inline void cache_enq(struct gnttab_page_cache *cache, struct page *page)
838+
{
839+
page->zone_device_data = cache->pages;
840+
cache->pages = page;
841+
}
842+
#else
843+
static inline void cache_init(struct gnttab_page_cache *cache)
844+
{
845+
INIT_LIST_HEAD(&cache->pages);
846+
}
847+
848+
static inline bool cache_empty(struct gnttab_page_cache *cache)
849+
{
850+
return list_empty(&cache->pages);
851+
}
852+
853+
static inline struct page *cache_deq(struct gnttab_page_cache *cache)
854+
{
855+
struct page *page;
856+
857+
page = list_first_entry(&cache->pages, struct page, lru);
858+
list_del(&page->lru);
859+
860+
return page;
861+
}
862+
863+
static inline void cache_enq(struct gnttab_page_cache *cache, struct page *page)
864+
{
865+
list_add(&page->lru, &cache->pages);
866+
}
867+
#endif
868+
869+
void gnttab_page_cache_init(struct gnttab_page_cache *cache)
870+
{
871+
spin_lock_init(&cache->lock);
872+
cache_init(cache);
873+
cache->num_pages = 0;
874+
}
875+
EXPORT_SYMBOL_GPL(gnttab_page_cache_init);
876+
877+
int gnttab_page_cache_get(struct gnttab_page_cache *cache, struct page **page)
878+
{
879+
unsigned long flags;
880+
881+
spin_lock_irqsave(&cache->lock, flags);
882+
883+
if (cache_empty(cache)) {
884+
spin_unlock_irqrestore(&cache->lock, flags);
885+
return gnttab_alloc_pages(1, page);
886+
}
887+
888+
page[0] = cache_deq(cache);
889+
cache->num_pages--;
890+
891+
spin_unlock_irqrestore(&cache->lock, flags);
892+
893+
return 0;
894+
}
895+
EXPORT_SYMBOL_GPL(gnttab_page_cache_get);
896+
897+
void gnttab_page_cache_put(struct gnttab_page_cache *cache, struct page **page,
898+
unsigned int num)
899+
{
900+
unsigned long flags;
901+
unsigned int i;
902+
903+
spin_lock_irqsave(&cache->lock, flags);
904+
905+
for (i = 0; i < num; i++)
906+
cache_enq(cache, page[i]);
907+
cache->num_pages += num;
908+
909+
spin_unlock_irqrestore(&cache->lock, flags);
910+
}
911+
EXPORT_SYMBOL_GPL(gnttab_page_cache_put);
912+
913+
void gnttab_page_cache_shrink(struct gnttab_page_cache *cache, unsigned int num)
914+
{
915+
struct page *page[10];
916+
unsigned int i = 0;
917+
unsigned long flags;
918+
919+
spin_lock_irqsave(&cache->lock, flags);
920+
921+
while (cache->num_pages > num) {
922+
page[i] = cache_deq(cache);
923+
cache->num_pages--;
924+
if (++i == ARRAY_SIZE(page)) {
925+
spin_unlock_irqrestore(&cache->lock, flags);
926+
gnttab_free_pages(i, page);
927+
i = 0;
928+
spin_lock_irqsave(&cache->lock, flags);
929+
}
930+
}
931+
932+
spin_unlock_irqrestore(&cache->lock, flags);
933+
934+
if (i != 0)
935+
gnttab_free_pages(i, page);
936+
}
937+
EXPORT_SYMBOL_GPL(gnttab_page_cache_shrink);
938+
816939
void gnttab_pages_clear_private(int nr_pages, struct page **pages)
817940
{
818941
int i;

drivers/xen/unpopulated-alloc.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
#include <xen/xen.h>
1313

1414
static DEFINE_MUTEX(list_lock);
15-
static LIST_HEAD(page_list);
15+
static struct page *page_list;
1616
static unsigned int list_count;
1717

1818
static int fill_list(unsigned int nr_pages)
@@ -84,7 +84,8 @@ static int fill_list(unsigned int nr_pages)
8484
struct page *pg = virt_to_page(vaddr + PAGE_SIZE * i);
8585

8686
BUG_ON(!virt_addr_valid(vaddr + PAGE_SIZE * i));
87-
list_add(&pg->lru, &page_list);
87+
pg->zone_device_data = page_list;
88+
page_list = pg;
8889
list_count++;
8990
}
9091

@@ -118,12 +119,10 @@ int xen_alloc_unpopulated_pages(unsigned int nr_pages, struct page **pages)
118119
}
119120

120121
for (i = 0; i < nr_pages; i++) {
121-
struct page *pg = list_first_entry_or_null(&page_list,
122-
struct page,
123-
lru);
122+
struct page *pg = page_list;
124123

125124
BUG_ON(!pg);
126-
list_del(&pg->lru);
125+
page_list = pg->zone_device_data;
127126
list_count--;
128127
pages[i] = pg;
129128

@@ -134,7 +133,8 @@ int xen_alloc_unpopulated_pages(unsigned int nr_pages, struct page **pages)
134133
unsigned int j;
135134

136135
for (j = 0; j <= i; j++) {
137-
list_add(&pages[j]->lru, &page_list);
136+
pages[j]->zone_device_data = page_list;
137+
page_list = pages[j];
138138
list_count++;
139139
}
140140
goto out;
@@ -160,7 +160,8 @@ void xen_free_unpopulated_pages(unsigned int nr_pages, struct page **pages)
160160

161161
mutex_lock(&list_lock);
162162
for (i = 0; i < nr_pages; i++) {
163-
list_add(&pages[i]->lru, &page_list);
163+
pages[i]->zone_device_data = page_list;
164+
page_list = pages[i];
164165
list_count++;
165166
}
166167
mutex_unlock(&list_lock);
@@ -189,7 +190,8 @@ static int __init init(void)
189190
struct page *pg =
190191
pfn_to_page(xen_extra_mem[i].start_pfn + j);
191192

192-
list_add(&pg->lru, &page_list);
193+
pg->zone_device_data = page_list;
194+
page_list = pg;
193195
list_count++;
194196
}
195197
}

0 commit comments

Comments
 (0)