.. | .. |
---|
99 | 99 | struct list_head v2p_entry_lists; |
---|
100 | 100 | |
---|
101 | 101 | wait_queue_head_t waiting_to_free; |
---|
| 102 | + |
---|
| 103 | + struct gnttab_page_cache free_pages; |
---|
102 | 104 | }; |
---|
103 | 105 | |
---|
104 | 106 | /* theoretical maximum of grants for one request */ |
---|
.. | .. |
---|
188 | 190 | MODULE_PARM_DESC(max_buffer_pages, |
---|
189 | 191 | "Maximum number of free pages to keep in backend buffer"); |
---|
190 | 192 | |
---|
191 | | -static DEFINE_SPINLOCK(free_pages_lock); |
---|
192 | | -static int free_pages_num; |
---|
193 | | -static LIST_HEAD(scsiback_free_pages); |
---|
194 | | - |
---|
195 | 193 | /* Global spinlock to protect scsiback TPG list */ |
---|
196 | 194 | static DEFINE_MUTEX(scsiback_mutex); |
---|
197 | 195 | static LIST_HEAD(scsiback_list); |
---|
.. | .. |
---|
205 | 203 | { |
---|
206 | 204 | if (atomic_dec_and_test(&info->nr_unreplied_reqs)) |
---|
207 | 205 | wake_up(&info->waiting_to_free); |
---|
208 | | -} |
---|
209 | | - |
---|
210 | | -static void put_free_pages(struct page **page, int num) |
---|
211 | | -{ |
---|
212 | | - unsigned long flags; |
---|
213 | | - int i = free_pages_num + num, n = num; |
---|
214 | | - |
---|
215 | | - if (num == 0) |
---|
216 | | - return; |
---|
217 | | - if (i > scsiback_max_buffer_pages) { |
---|
218 | | - n = min(num, i - scsiback_max_buffer_pages); |
---|
219 | | - gnttab_free_pages(n, page + num - n); |
---|
220 | | - n = num - n; |
---|
221 | | - } |
---|
222 | | - spin_lock_irqsave(&free_pages_lock, flags); |
---|
223 | | - for (i = 0; i < n; i++) |
---|
224 | | - list_add(&page[i]->lru, &scsiback_free_pages); |
---|
225 | | - free_pages_num += n; |
---|
226 | | - spin_unlock_irqrestore(&free_pages_lock, flags); |
---|
227 | | -} |
---|
228 | | - |
---|
229 | | -static int get_free_page(struct page **page) |
---|
230 | | -{ |
---|
231 | | - unsigned long flags; |
---|
232 | | - |
---|
233 | | - spin_lock_irqsave(&free_pages_lock, flags); |
---|
234 | | - if (list_empty(&scsiback_free_pages)) { |
---|
235 | | - spin_unlock_irqrestore(&free_pages_lock, flags); |
---|
236 | | - return gnttab_alloc_pages(1, page); |
---|
237 | | - } |
---|
238 | | - page[0] = list_first_entry(&scsiback_free_pages, struct page, lru); |
---|
239 | | - list_del(&page[0]->lru); |
---|
240 | | - free_pages_num--; |
---|
241 | | - spin_unlock_irqrestore(&free_pages_lock, flags); |
---|
242 | | - return 0; |
---|
243 | 206 | } |
---|
244 | 207 | |
---|
245 | 208 | static unsigned long vaddr_page(struct page *page) |
---|
.. | .. |
---|
302 | 265 | BUG_ON(err); |
---|
303 | 266 | } |
---|
304 | 267 | |
---|
305 | | - put_free_pages(req->pages, req->n_grants); |
---|
| 268 | + gnttab_page_cache_put(&req->info->free_pages, req->pages, |
---|
| 269 | + req->n_grants); |
---|
306 | 270 | req->n_grants = 0; |
---|
307 | 271 | } |
---|
308 | 272 | |
---|
.. | .. |
---|
445 | 409 | struct vscsibk_info *info = pending_req->info; |
---|
446 | 410 | |
---|
447 | 411 | for (i = 0; i < cnt; i++) { |
---|
448 | | - if (get_free_page(pg + mapcount)) { |
---|
449 | | - put_free_pages(pg, mapcount); |
---|
| 412 | + if (gnttab_page_cache_get(&info->free_pages, pg + mapcount)) { |
---|
| 413 | + gnttab_page_cache_put(&info->free_pages, pg, mapcount); |
---|
450 | 414 | pr_err("no grant page\n"); |
---|
451 | 415 | return -ENOMEM; |
---|
452 | 416 | } |
---|
.. | .. |
---|
796 | 760 | cond_resched(); |
---|
797 | 761 | } |
---|
798 | 762 | |
---|
| 763 | + gnttab_page_cache_shrink(&info->free_pages, scsiback_max_buffer_pages); |
---|
| 764 | + |
---|
799 | 765 | RING_FINAL_CHECK_FOR_REQUESTS(&info->ring, more_to_do); |
---|
800 | 766 | return more_to_do; |
---|
801 | 767 | } |
---|
.. | .. |
---|
858 | 824 | static int scsiback_map(struct vscsibk_info *info) |
---|
859 | 825 | { |
---|
860 | 826 | struct xenbus_device *dev = info->dev; |
---|
861 | | - unsigned int ring_ref, evtchn; |
---|
| 827 | + unsigned int ring_ref; |
---|
| 828 | + evtchn_port_t evtchn; |
---|
862 | 829 | int err; |
---|
863 | 830 | |
---|
864 | 831 | err = xenbus_gather(XBT_NIL, dev->otherend, |
---|
.. | .. |
---|
1188 | 1155 | xenbus_switch_state(dev, XenbusStateClosed); |
---|
1189 | 1156 | if (xenbus_dev_is_online(dev)) |
---|
1190 | 1157 | break; |
---|
1191 | | - /* fall through if not online */ |
---|
| 1158 | + fallthrough; /* if not online */ |
---|
1192 | 1159 | case XenbusStateUnknown: |
---|
1193 | 1160 | device_unregister(&dev->dev); |
---|
1194 | 1161 | break; |
---|
.. | .. |
---|
1232 | 1199 | |
---|
1233 | 1200 | scsiback_release_translation_entry(info); |
---|
1234 | 1201 | |
---|
| 1202 | + gnttab_page_cache_shrink(&info->free_pages, 0); |
---|
| 1203 | + |
---|
1235 | 1204 | dev_set_drvdata(&dev->dev, NULL); |
---|
1236 | 1205 | |
---|
1237 | 1206 | return 0; |
---|
.. | .. |
---|
1262 | 1231 | info->irq = 0; |
---|
1263 | 1232 | INIT_LIST_HEAD(&info->v2p_entry_lists); |
---|
1264 | 1233 | spin_lock_init(&info->v2p_lock); |
---|
| 1234 | + gnttab_page_cache_init(&info->free_pages); |
---|
1265 | 1235 | |
---|
1266 | 1236 | err = xenbus_printf(XBT_NIL, dev->nodename, "feature-sg-grant", "%u", |
---|
1267 | 1237 | SG_ALL); |
---|
.. | .. |
---|
1404 | 1374 | /* Go ahead and process the write immediately */ |
---|
1405 | 1375 | target_execute_cmd(se_cmd); |
---|
1406 | 1376 | |
---|
1407 | | - return 0; |
---|
1408 | | -} |
---|
1409 | | - |
---|
1410 | | -static int scsiback_write_pending_status(struct se_cmd *se_cmd) |
---|
1411 | | -{ |
---|
1412 | 1377 | return 0; |
---|
1413 | 1378 | } |
---|
1414 | 1379 | |
---|
.. | .. |
---|
1715 | 1680 | NULL, |
---|
1716 | 1681 | }; |
---|
1717 | 1682 | |
---|
1718 | | -static char *scsiback_get_fabric_name(void) |
---|
1719 | | -{ |
---|
1720 | | - return "xen-pvscsi"; |
---|
1721 | | -} |
---|
1722 | | - |
---|
1723 | 1683 | static int scsiback_port_link(struct se_portal_group *se_tpg, |
---|
1724 | 1684 | struct se_lun *lun) |
---|
1725 | 1685 | { |
---|
.. | .. |
---|
1813 | 1773 | |
---|
1814 | 1774 | static const struct target_core_fabric_ops scsiback_ops = { |
---|
1815 | 1775 | .module = THIS_MODULE, |
---|
1816 | | - .name = "xen-pvscsi", |
---|
1817 | | - .get_fabric_name = scsiback_get_fabric_name, |
---|
| 1776 | + .fabric_name = "xen-pvscsi", |
---|
1818 | 1777 | .tpg_get_wwn = scsiback_get_fabric_wwn, |
---|
1819 | 1778 | .tpg_get_tag = scsiback_get_tag, |
---|
1820 | 1779 | .tpg_check_demo_mode = scsiback_check_true, |
---|
.. | .. |
---|
1827 | 1786 | .sess_get_index = scsiback_sess_get_index, |
---|
1828 | 1787 | .sess_get_initiator_sid = NULL, |
---|
1829 | 1788 | .write_pending = scsiback_write_pending, |
---|
1830 | | - .write_pending_status = scsiback_write_pending_status, |
---|
1831 | 1789 | .set_default_node_attributes = scsiback_set_default_node_attrs, |
---|
1832 | 1790 | .get_cmd_state = scsiback_get_cmd_state, |
---|
1833 | 1791 | .queue_data_in = scsiback_queue_data_in, |
---|
.. | .. |
---|
1890 | 1848 | |
---|
1891 | 1849 | static void __exit scsiback_exit(void) |
---|
1892 | 1850 | { |
---|
1893 | | - struct page *page; |
---|
1894 | | - |
---|
1895 | | - while (free_pages_num) { |
---|
1896 | | - if (get_free_page(&page)) |
---|
1897 | | - BUG(); |
---|
1898 | | - gnttab_free_pages(1, &page); |
---|
1899 | | - } |
---|
1900 | 1851 | target_unregister_template(&scsiback_ops); |
---|
1901 | 1852 | xenbus_unregister_driver(&scsiback_driver); |
---|
1902 | 1853 | } |
---|