函数源码 |
Source File:mm\migrate.c |
Create Date:2022-07-27 17:33:43 |
首页 | Copyright©Brick |
1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 | /* * Migrate an array of page address onto an array of nodes and fill * the corresponding array of status. */ static int do_pages_move( struct mm_struct *mm, nodemask_t task_nodes, unsigned long nr_pages, const void __user * __user *pages, const int __user *nodes, int __user *status, int flags) { int current_node = NUMA_NO_NODE; LIST_HEAD(pagelist); int start, i; int err = 0, err1; migrate_prep(); for (i = start = 0; i < nr_pages; i++) { const void __user *p; unsigned long addr; int node; err = -EFAULT; if (get_user(p, pages + i)) goto out_flush; if (get_user(node, nodes + i)) goto out_flush; addr = (unsigned long )untagged_addr(p); err = -ENODEV; if (node < 0 || node >= MAX_NUMNODES) goto out_flush; if (!node_state(node, N_MEMORY)) goto out_flush; err = -EACCES; if (!node_isset(node, task_nodes)) goto out_flush; if (current_node == NUMA_NO_NODE) { current_node = node; start = i; } else if (node != current_node) { err = do_move_pages_to_node(mm, &pagelist, current_node); if (err) { /* * Positive err means the number of failed * pages to migrate. Since we are going to * abort and return the number of non-migrated * pages, so need to incude the rest of the * nr_pages that have not been attempted as * well. */ if (err > 0) err += nr_pages - i - 1; goto out; } err = store_status(status, start, current_node, i - start); if (err) goto out; start = i; current_node = node; } /* * Errors in the page lookup or isolation are not fatal and we simply * report them via status */ err = add_page_for_migration(mm, addr, current_node, &pagelist, flags & MPOL_MF_MOVE_ALL); if (!err) { /* The page is already on the target node */ err = store_status(status, i, current_node, 1); if (err) goto out_flush; continue ; } else if (err > 0) { /* The page is successfully queued for migration */ continue ; } err = store_status(status, i, err, 1); if (err) goto out_flush; err = do_move_pages_to_node(mm, &pagelist, current_node); if (err) { if (err > 0) err += nr_pages - i - 1; goto out; } if (i > start) { err = store_status(status, start, current_node, i - start); if (err) goto out; } current_node = NUMA_NO_NODE; } out_flush: if (list_empty(&pagelist)) return err; /* Make sure we do not overwrite the existing error */ err1 = do_move_pages_to_node(mm, &pagelist, current_node); /* * Don't have to report non-attempted pages here since: * - If the above loop is done gracefully all pages have been * attempted. * - If the above loop is aborted it means a fatal error * happened, should return ret. */ if (!err1) err1 = store_status(status, start, current_node, i - start); if (err >= 0) err = err1; out: return err; } |