diff --git a/study/kernel/02-memory/04-buddy/04-alloc_page/README.md b/study/kernel/02-memory/04-buddy/04-alloc_page/README.md index 183f075..fa6e81d 100755 --- a/study/kernel/02-memory/04-buddy/04-alloc_page/README.md +++ b/study/kernel/02-memory/04-buddy/04-alloc_page/README.md @@ -945,12 +945,50 @@ static struct page *__rmqueue_pcplist(struct zone *zone, int migratetype, } ``` -### 3.4.3 ` __rmqueue` +* 如果 PCP list 是空的, 那么会通过 [`rmqueue_bulk`](https://elixir.bootlin.com/linux/v5.10/source/mm/page_alloc.c#L2880) 从 buddy 伙伴系统分配 pcp->batch 个页面出来. + +* 否则, PCP 中有页面, 则直接取一个页面出来. + +### 3.4.3 ` __rmqueue_smallest` ------- -### 3.4.4 `__rmqueue_smallest` +`__rmqueue` 主体是通过 `__rmqueue_smallest` 来向 buddy 伙伴系统中像切蛋糕一样, 切出一块内存出来的. + +```cpp +// https://elixir.bootlin.com/linux/v5.10/source/mm/page_alloc.c#L2303 +/* + * Go through the free lists for the given migratetype and remove + * the smallest available page from the freelists + */ +static __always_inline +struct page *__rmqueue_smallest(struct zone *zone, unsigned int order, + int migratetype) +{ + unsigned int current_order; + struct free_area *area; + struct page *page; + + /* Find a page of the appropriate size in the preferred list */ + for (current_order = order; current_order < MAX_ORDER; ++current_order) { + area = &(zone->free_area[current_order]); + page = get_page_from_free_area(area, migratetype); + if (!page) + continue; + del_page_from_free_list(page, zone, current_order); + expand(zone, page, order, current_order, migratetype); + set_pcppage_migratetype(page, migratetype); + return page; + } + + return NULL; +} +``` + + +![`__rmqueue_fallback` 流程](./__rmqueue_fallback.png) + +### 3.4.4 `__rmqueue_fallback` ------- - -### 3.4.5 __rmqueue_fallback \ No newline at end of file +如果前面的流程都分配失败了, 那么说明当前 ZONG 区域指定 MIGRATE_TYPE 中没有足够的空闲页来完成本次分配了. 那么内核此时将尝试 \ No newline at end of file diff --git a/study/kernel/02-memory/04-buddy/04-alloc_page/__rmqueue_fallback.png b/study/kernel/02-memory/04-buddy/04-alloc_page/__rmqueue_fallback.png new file mode 100755 index 0000000..7d1cd53 Binary files /dev/null and b/study/kernel/02-memory/04-buddy/04-alloc_page/__rmqueue_fallback.png differ diff --git a/study/kernel/02-memory/04-buddy/04-alloc_page/__rmqueue_smallest.excalidraw b/study/kernel/02-memory/04-buddy/04-alloc_page/__rmqueue_smallest.excalidraw new file mode 100755 index 0000000..57b9a5c --- /dev/null +++ b/study/kernel/02-memory/04-buddy/04-alloc_page/__rmqueue_smallest.excalidraw @@ -0,0 +1,849 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "type": "rectangle", + "version": 422, + "versionNonce": 1768024381, + "isDeleted": false, + "id": "ecl-R4U0938S-pLr9rcnO", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 496.5, + "y": -398.75, + "strokeColor": "#000000", + "backgroundColor": "#82c91e", + "width": 244.99999999999997, + "height": 35.000000000000014, + "seed": 2034558099, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElementIds": [ + "hC97PmiA9GpSyZPfCGdGv", + "3SxvWp5giaQFb8YaHyiTB", + "QN25t4_XOP7-HRxAuV7Y2", + "DhBK1onobgdtoteMzJ3RY", + "EVuGS3oXm7jYXCy8DsY2V", + "7-zXi5_a33f7uUIc7_j_9", + "OWrGRSWgDTVld8aCb9xUP", + "E-FoU4T3WQM9Nik2oNqPM" + ] + }, + { + "type": "text", + "version": 191, + "versionNonce": 764209075, + "isDeleted": false, + "id": "oUUBFejDTRBHWWkuwFoQw", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 506.5, + "y": -395.75, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 199, + "height": 27, + "seed": 1431806493, + "groupIds": [], + "strokeSharpness": "round", + "boundElementIds": [ + "QN25t4_XOP7-HRxAuV7Y2", + "VGI_QGiy6and7H_GNB7Pc", + "nGXxbhYzARGmuHcQu1X-m", + "da_QjUCCbuWHuwwdCnmce", + "3Z5N2bPTf1bVJLbbIiyt9", + "go0z08x204Flj3kcsqo3C" + ], + "fontSize": 20, + "fontFamily": 1, + "text": " __rmqueue_smallest", + "baseline": 20, + "textAlign": "left", + "verticalAlign": "top" + }, + { + "type": "rectangle", + "version": 738, + "versionNonce": 791394717, + "isDeleted": false, + "id": "EbDc6C8ufCSbZKUC70gKI", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 630, + "y": -226.25, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 290, + "height": 34.99999999999998, + "seed": 117496371, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElementIds": [ + "hC97PmiA9GpSyZPfCGdGv", + "3SxvWp5giaQFb8YaHyiTB" + ] + }, + { + "type": "text", + "version": 564, + "versionNonce": 1975253683, + "isDeleted": false, + "id": "RUCxE170I2EL-qcImvR-P", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 641, + "y": -223.25, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 256, + "height": 27, + "seed": 163010173, + "groupIds": [], + "strokeSharpness": "round", + "boundElementIds": [ + "EVuGS3oXm7jYXCy8DsY2V", + "_vUFgioABe191JEmcUjY2", + "q_mz5DSo6wG_4fphd9wjX" + ], + "fontSize": 20, + "fontFamily": 1, + "text": "get_page_from_free_area", + "baseline": 20, + "textAlign": "left", + "verticalAlign": "top" + }, + { + "type": "text", + "version": 899, + "versionNonce": 1344044541, + "isDeleted": false, + "id": "cSGZ20rNhSVIYG5p6O7Cs", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 546, + "y": -343.25, + "strokeColor": "#000000", + "backgroundColor": "#82c91e", + "width": 740, + "height": 23, + "seed": 283974611, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElementIds": [ + "7-zXi5_a33f7uUIc7_j_9" + ], + "fontSize": 16, + "fontFamily": 1, + "text": "从当前 order 开始遍历,当前 order 可能没有足够的页面时我们不得不从大 order 的页面池中切页面出来", + "baseline": 17, + "textAlign": "center", + "verticalAlign": "top" + }, + { + "type": "rectangle", + "version": 852, + "versionNonce": 1847968029, + "isDeleted": false, + "id": "r7bAEK9IpET2crUEtRCVK", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 632, + "y": -146.25, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 276, + "height": 35.00000000000003, + "seed": 350322397, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElementIds": [ + "hC97PmiA9GpSyZPfCGdGv", + "3SxvWp5giaQFb8YaHyiTB", + "zpjUFLxXP8i6UxY1iM2Tp" + ] + }, + { + "type": "text", + "version": 448, + "versionNonce": 972283357, + "isDeleted": false, + "id": "3x4r41_K5r69Yko2mvgb6", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 648, + "y": -143.25, + "strokeColor": "#000000", + "backgroundColor": "#82c91e", + "width": 229, + "height": 27, + "seed": 1126181235, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElementIds": [ + "BPvtJ4i7uXdRMiNM_nAFL", + "m2-2gfSFQsgKHJlzp6KqU", + "FgeP59vY1NQV90puDkYug", + "e327d1TRmieUKwM0YdTFP", + "9kYZC9Z5kbOeE4AbGBwcz" + ], + "fontSize": 20, + "fontFamily": 1, + "text": "del_page_from_free_list", + "baseline": 20, + "textAlign": "center", + "verticalAlign": "top" + }, + { + "type": "rectangle", + "version": 1077, + "versionNonce": 216869363, + "isDeleted": false, + "id": "1BzNZstcH1RTORj_kupMS", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 632.5, + "y": -73.25, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 87, + "height": 37.00000000000002, + "seed": 493329213, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElementIds": [ + "hC97PmiA9GpSyZPfCGdGv", + "3SxvWp5giaQFb8YaHyiTB", + "YooWyMdEU0zQBm9l9Ja_9" + ] + }, + { + "type": "text", + "version": 564, + "versionNonce": 2084139923, + "isDeleted": false, + "id": "flCK9Dzr2EUWqbHZNSLcq", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 642.5, + "y": -64.75, + "strokeColor": "#000000", + "backgroundColor": "#82c91e", + "width": 61, + "height": 22, + "seed": 2074815389, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElementIds": [ + "8wHI9J5ManjEE62c5Xi8d", + "YooWyMdEU0zQBm9l9Ja_9", + "qgiKz46xXy9aGJWX0h2iq" + ], + "fontSize": 16, + "fontFamily": 1, + "text": "expand", + "baseline": 16, + "textAlign": "left", + "verticalAlign": "top" + }, + { + "type": "arrow", + "version": 490, + "versionNonce": 351765277, + "isDeleted": false, + "id": "q_mz5DSo6wG_4fphd9wjX", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 532.5, + "y": -205.75, + "strokeColor": "#000000", + "backgroundColor": "#82c91e", + "width": 100, + "height": 0.84960386043565, + "seed": 1218750643, + "groupIds": [], + "strokeSharpness": "round", + "boundElementIds": [], + "startBinding": null, + "endBinding": { + "elementId": "RUCxE170I2EL-qcImvR-P", + "focus": -0.41194968553458894, + "gap": 8.5 + }, + "points": [ + [ + 0, + 0 + ], + [ + 100, + 0.84960386043565 + ] + ], + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "type": "arrow", + "version": 353, + "versionNonce": 1823676285, + "isDeleted": false, + "id": "bGOiUi-JA1ibR-B1uYYEI", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 527.5, + "y": -81.75, + "strokeColor": "#000000", + "backgroundColor": "#82c91e", + "width": 0, + "height": 0, + "seed": 974330451, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElementIds": [], + "startBinding": null, + "endBinding": null, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "type": "arrow", + "version": 298, + "versionNonce": 1028254419, + "isDeleted": false, + "id": "wC8LV4QWbUA8zyl8vk0yk", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 522.5, + "y": -176.75, + "strokeColor": "#000000", + "backgroundColor": "#82c91e", + "width": 0, + "height": 0, + "seed": 2013309021, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElementIds": [], + "startBinding": null, + "endBinding": null, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "type": "arrow", + "version": 769, + "versionNonce": 79503325, + "isDeleted": false, + "id": "YooWyMdEU0zQBm9l9Ja_9", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 542.5, + "y": -53.75, + "strokeColor": "#000000", + "backgroundColor": "#82c91e", + "width": 90, + "height": 2.1792806081924425, + "seed": 67262451, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElementIds": [], + "startBinding": null, + "endBinding": { + "elementId": "flCK9Dzr2EUWqbHZNSLcq", + "focus": -0.2691951896392229, + "gap": 10 + }, + "points": [ + [ + 0, + 0 + ], + [ + 90, + 2.1792806081924425 + ] + ], + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "type": "text", + "version": 1043, + "versionNonce": 1564067987, + "isDeleted": false, + "id": "4hLCSLTiHUath35OXyh2c", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 640, + "y": -96.75, + "strokeColor": "#000000", + "backgroundColor": "#82c91e", + "width": 623, + "height": 23, + "seed": 809500317, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElementIds": [], + "fontSize": 16, + "fontFamily": 1, + "text": "当取出的 current_order > order 的时候,我们需要将页面切开,多余部分放回到buddy", + "baseline": 17, + "textAlign": "center", + "verticalAlign": "top" + }, + { + "type": "rectangle", + "version": 1143, + "versionNonce": 216642269, + "isDeleted": false, + "id": "TY22LtJ7_XK182EFhX0CZ", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 633, + "y": 9.5, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 275.99999999999994, + "height": 41.00000000000002, + "seed": 1623062013, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElementIds": [ + "hC97PmiA9GpSyZPfCGdGv", + "3SxvWp5giaQFb8YaHyiTB" + ] + }, + { + "id": "3zXu1dctYoXmKHCIyyWjP", + "type": "text", + "x": 645, + "y": 18, + "width": 261, + "height": 27, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 1367433533, + "version": 254, + "versionNonce": 1441084787, + "isDeleted": false, + "boundElementIds": [ + "czWsi9oqkewLtN03iXp90" + ], + "text": "set_pcppage_migratetype", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 20 + }, + { + "type": "arrow", + "version": 806, + "versionNonce": 1313427261, + "isDeleted": false, + "id": "czWsi9oqkewLtN03iXp90", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 543, + "y": 29.910359695903765, + "strokeColor": "#000000", + "backgroundColor": "#82c91e", + "width": 90, + "height": 2.1792806081924425, + "seed": 458541021, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElementIds": [], + "startBinding": null, + "endBinding": { + "elementId": "3zXu1dctYoXmKHCIyyWjP", + "focus": -0.24250770649524978, + "gap": 12 + }, + "points": [ + [ + 0, + 0 + ], + [ + 90, + 2.1792806081924425 + ] + ], + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "type": "rectangle", + "version": 814, + "versionNonce": 1228347315, + "isDeleted": false, + "id": "ufkNs7wjkbdGLoOWdkbZ_", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 534, + "y": -309.5, + "strokeColor": "#000000", + "backgroundColor": "#fab005", + "width": 758.0000000000001, + "height": 42.00000000000002, + "seed": 255891645, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElementIds": [ + "hC97PmiA9GpSyZPfCGdGv", + "3SxvWp5giaQFb8YaHyiTB", + "da_QjUCCbuWHuwwdCnmce", + "_spanIrdskZTqTknwLUZa" + ] + }, + { + "id": "fyNDIVXLx5KiqGR5Oi5lf", + "type": "text", + "x": 566, + "y": -304, + "width": 702, + "height": 27, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 1256279539, + "version": 88, + "versionNonce": 542039133, + "isDeleted": false, + "boundElementIds": null, + "text": "for (current_order = order; current_order < MAX_ORDER; ++current_order)", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 20 + }, + { + "id": "h8I9tQdbqfNzMmxw7lnhp", + "type": "text", + "x": 631, + "y": -252, + "width": 417, + "height": 23, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "#fab005", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 741539123, + "version": 134, + "versionNonce": 840519699, + "isDeleted": false, + "boundElementIds": null, + "text": "取出当前 current_order 对应 migrate_type 的第一个页面", + "fontSize": 16, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 17 + }, + { + "id": "zpjUFLxXP8i6UxY1iM2Tp", + "type": "arrow", + "x": 537, + "y": -125, + "width": 95, + "height": 0, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "#fab005", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "round", + "seed": 1587378707, + "version": 25, + "versionNonce": 1778537875, + "isDeleted": false, + "boundElementIds": null, + "points": [ + [ + 0, + 0 + ], + [ + 95, + 0 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": { + "elementId": "r7bAEK9IpET2crUEtRCVK", + "focus": -0.2142857142857141, + "gap": 1 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "_zVdKPYq9iRaujS6cmQts", + "type": "text", + "x": 629, + "y": -169.5, + "width": 244, + "height": 23, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "#fab005", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 1155363859, + "version": 179, + "versionNonce": 129555133, + "isDeleted": false, + "boundElementIds": null, + "text": "将取出的页面从 free_area 中移除", + "fontSize": 16, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 17 + }, + { + "type": "text", + "version": 1288, + "versionNonce": 1284303379, + "isDeleted": false, + "id": "dlNnMK5bKtj4P5dMwnfo6", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 641, + "y": -17.5, + "strokeColor": "#000000", + "backgroundColor": "#82c91e", + "width": 558, + "height": 23, + "seed": 1065684861, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElementIds": [], + "fontSize": 16, + "fontFamily": 1, + "text": "fallback 情况下,会从其他 migrate_type 窃取的内存,migrate_type 要设置", + "baseline": 17, + "textAlign": "center", + "verticalAlign": "top" + }, + { + "id": "D7MDS4Pm1KTO2tvR1_tVP", + "type": "line", + "x": 534, + "y": -268, + "width": 12, + "height": 299, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "#fab005", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 1923977555, + "version": 75, + "versionNonce": 89117043, + "isDeleted": false, + "boundElementIds": null, + "points": [ + [ + 0, + 0 + ], + [ + 12, + 299 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null + }, + { + "id": "go0z08x204Flj3kcsqo3C", + "type": "arrow", + "x": 505, + "y": -365, + "width": 32, + "height": 81, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "#fab005", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 822759603, + "version": 48, + "versionNonce": 2080144541, + "isDeleted": false, + "boundElementIds": null, + "points": [ + [ + 0, + 0 + ], + [ + 6, + 81 + ], + [ + 32, + 80 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "oUUBFejDTRBHWWkuwFoQw", + "focus": 1.017689331122167, + "gap": 3.75 + }, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow" + } + ], + "appState": { + "gridSize": null, + "viewBackgroundColor": "#ffffff" + } +} \ No newline at end of file