Skip to content

Commit

Permalink
Changes representative of linux-3.10.0-123.el7.tar.xz
Browse files Browse the repository at this point in the history
  • Loading branch information
da-x committed Dec 21, 2015
1 parent 5d7dbe5 commit 39338bc
Show file tree
Hide file tree
Showing 9 changed files with 276 additions and 74 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ EXTRAVERSION =
NAME = Unicycling Gorilla
RHEL_MAJOR = 7
RHEL_MINOR = 0
RHEL_RELEASE = 121
RHEL_RELEASE = 123

# *DOCUMENTATION*
# To see a list of typical targets execute "make help"
Expand Down
5 changes: 5 additions & 0 deletions drivers/misc/mei/hw-me-regs.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,11 @@
#define MEI_DEV_ID_LPT_HR 0x8CBA /* Lynx Point H Refresh */

#define MEI_DEV_ID_WPT_LP 0x9CBA /* Wildcat Point LP */

/* Host Firmware Status Registers in PCI Config Space */
#define PCI_CFG_HFS_1 0x40
#define PCI_CFG_HFS_2 0x48

/*
* MEI HW Section
*/
Expand Down
30 changes: 23 additions & 7 deletions drivers/misc/mei/pci-me.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,15 +105,31 @@ static bool mei_me_quirk_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
u32 reg;
if (ent->device == MEI_DEV_ID_PBG_1) {
pci_read_config_dword(pdev, 0x48, &reg);
/* make sure that bit 9 is up and bit 10 is down */
if ((reg & 0x600) == 0x200) {
dev_info(&pdev->dev, "Device doesn't have valid ME Interface\n");
return false;
}
/* Cougar Point || Patsburg */
if (ent->device == MEI_DEV_ID_CPT_1 ||
ent->device == MEI_DEV_ID_PBG_1) {
pci_read_config_dword(pdev, PCI_CFG_HFS_2, &reg);
/* make sure that bit 9 (NM) is up and bit 10 (DM) is down */
if ((reg & 0x600) == 0x200)
goto no_mei;
}

/* Lynx Point */
if (ent->device == MEI_DEV_ID_LPT_H ||
ent->device == MEI_DEV_ID_LPT_W ||
ent->device == MEI_DEV_ID_LPT_HR) {
/* Read ME FW Status check for SPS Firmware */
pci_read_config_dword(pdev, PCI_CFG_HFS_1, &reg);
/* if bits [19:16] = 15, running SPS Firmware */
if ((reg & 0xf0000) == 0xf0000)
goto no_mei;
}

return true;

no_mei:
dev_info(&pdev->dev, "Device doesn't have valid ME Interface\n");
return false;
}
/**
* mei_probe - Device Initialization Routine
Expand Down
4 changes: 2 additions & 2 deletions fs/autofs4/root.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ static struct dentry *autofs4_lookup_active(struct dentry *dentry)
spin_lock(&active->d_lock);

/* Already gone? */
if (!d_count(active))
if ((int) d_count(active) <= 0)
goto next;

qstr = &active->d_name;
Expand Down Expand Up @@ -230,7 +230,7 @@ static struct dentry *autofs4_lookup_expiring(struct dentry *dentry)

spin_lock(&expiring->d_lock);

/* Bad luck, we've already been dentry_iput */
/* We've already been dentry_iput or unlinked */
if (!expiring->d_inode)
goto next;

Expand Down
53 changes: 44 additions & 9 deletions mm/huge_memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -2255,7 +2255,34 @@ static void khugepaged_alloc_sleep(void)
msecs_to_jiffies(khugepaged_alloc_sleep_millisecs));
}

static int khugepaged_node_load[MAX_NUMNODES];

#ifdef CONFIG_NUMA
static int khugepaged_find_target_node(void)
{
static int last_khugepaged_target_node = NUMA_NO_NODE;
int nid, target_node = 0, max_value = 0;

/* find first node with max normal pages hit */
for (nid = 0; nid < MAX_NUMNODES; nid++)
if (khugepaged_node_load[nid] > max_value) {
max_value = khugepaged_node_load[nid];
target_node = nid;
}

/* do some balance if several nodes have the same hit record */
if (target_node <= last_khugepaged_target_node)
for (nid = last_khugepaged_target_node + 1; nid < MAX_NUMNODES;
nid++)
if (max_value == khugepaged_node_load[nid]) {
target_node = nid;
break;
}

last_khugepaged_target_node = target_node;
return target_node;
}

static bool khugepaged_prealloc_page(struct page **hpage, bool *wait)
{
if (IS_ERR(*hpage)) {
Expand Down Expand Up @@ -2289,9 +2316,8 @@ static struct page
* mmap_sem in read mode is good idea also to allow greater
* scalability.
*/
*hpage = alloc_hugepage_vma(khugepaged_defrag(), vma, address,
node, __GFP_OTHER_NODE);

*hpage = alloc_pages_exact_node(node, alloc_hugepage_gfpmask(
khugepaged_defrag(), __GFP_OTHER_NODE), HPAGE_PMD_ORDER);
/*
* After allocating the hugepage, release the mmap_sem read lock in
* preparation for taking it in write mode.
Expand All @@ -2307,6 +2333,11 @@ static struct page
return *hpage;
}
#else
static int khugepaged_find_target_node(void)
{
return 0;
}

static struct page *khugepaged_alloc_hugepage(bool *wait)
{
struct page *hpage;
Expand Down Expand Up @@ -2512,6 +2543,7 @@ static int khugepaged_scan_pmd(struct mm_struct *mm,
if (pmd_trans_huge(*pmd))
goto out;

memset(khugepaged_node_load, 0, sizeof(khugepaged_node_load));
pte = pte_offset_map_lock(mm, pmd, address, &ptl);
for (_address = address, _pte = pte; _pte < pte+HPAGE_PMD_NR;
_pte++, _address += PAGE_SIZE) {
Expand All @@ -2528,12 +2560,13 @@ static int khugepaged_scan_pmd(struct mm_struct *mm,
if (unlikely(!page))
goto out_unmap;
/*
* Chose the node of the first page. This could
* be more sophisticated and look at more pages,
* but isn't for now.
* Record which node the original page is from and save this
* information to khugepaged_node_load[].
* Khupaged will allocate hugepage from the node has the max
* hit record.
*/
if (node == NUMA_NO_NODE)
node = page_to_nid(page);
node = page_to_nid(page);
khugepaged_node_load[node]++;
VM_BUG_ON(PageCompound(page));
if (!PageLRU(page) || PageLocked(page) || !PageAnon(page))
goto out_unmap;
Expand All @@ -2548,9 +2581,11 @@ static int khugepaged_scan_pmd(struct mm_struct *mm,
ret = 1;
out_unmap:
pte_unmap_unlock(pte, ptl);
if (ret)
if (ret) {
node = khugepaged_find_target_node();
/* collapse_huge_page will return with the mmap_sem released */
collapse_huge_page(mm, address, hpage, vma, node);
}
out:
return ret;
}
Expand Down
2 changes: 2 additions & 0 deletions mm/mlock.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ void clear_page_mlock(struct page *page)
*/
void mlock_vma_page(struct page *page)
{
/* Serialize with page migration */
BUG_ON(!PageLocked(page));

if (!TestSetPageMlocked(page)) {
Expand Down Expand Up @@ -106,6 +107,7 @@ unsigned int munlock_vma_page(struct page *page)
{
unsigned int page_mask = 0;

/* For try_to_munlock() and to serialize with page migration */
BUG_ON(!PageLocked(page));

if (TestClearPageMlocked(page)) {
Expand Down
40 changes: 30 additions & 10 deletions mm/mprotect.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,34 @@ static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
}
#endif

/*
* For a prot_numa update we only hold mmap_sem for read so there is a
* potential race with faulting where a pmd was temporarily none. This
* function checks for a transhuge pmd under the appropriate lock. It
* returns a pte if it was successfully locked or NULL if it raced with
* a transhuge insertion.
*/
static pte_t *lock_pte_protection(struct vm_area_struct *vma, pmd_t *pmd,
unsigned long addr, int prot_numa, spinlock_t **ptl)
{
pte_t *pte;
spinlock_t *pmdl;

/* !prot_numa is protected by mmap_sem held for write */
if (!prot_numa)
return pte_offset_map_lock(vma->vm_mm, pmd, addr, ptl);

pmdl = pmd_lock(vma->vm_mm, pmd);
if (unlikely(pmd_trans_huge(*pmd) || pmd_none(*pmd))) {
spin_unlock(pmdl);
return NULL;
}

pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, ptl);
spin_unlock(pmdl);
return pte;
}

static unsigned long change_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
unsigned long addr, unsigned long end, pgprot_t newprot,
int dirty_accountable, int prot_numa)
Expand All @@ -45,17 +73,9 @@ static unsigned long change_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
spinlock_t *ptl;
unsigned long pages = 0;

pte = pte_offset_map_lock(mm, pmd, addr, &ptl);

/*
* For a prot_numa update we only hold mmap_sem for read so there is a
* potential race with faulting where a pmd was temporarily none so
* recheck it under the lock and bail if we race
*/
if (prot_numa && unlikely(pmd_trans_huge(*pmd))) {
pte_unmap_unlock(pte, ptl);
pte = lock_pte_protection(vma, pmd, addr, prot_numa, &ptl);
if (!pte)
return 0;
}

arch_enter_lazy_mmu_mode();
do {
Expand Down
14 changes: 12 additions & 2 deletions mm/rmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1384,9 +1384,19 @@ static int try_to_unmap_cluster(unsigned long cursor, unsigned int *mapcount,
BUG_ON(!page || PageAnon(page));

if (locked_vma) {
mlock_vma_page(page); /* no-op if already mlocked */
if (page == check_page)
if (page == check_page) {
/* we know we have check_page locked */
mlock_vma_page(page);
ret = SWAP_MLOCK;
} else if (trylock_page(page)) {
/*
* If we can lock the page, perform mlock.
* Otherwise leave the page alone, it will be
* eventually encountered again later.
*/
mlock_vma_page(page);
unlock_page(page);
}
continue; /* don't unmap */
}

Expand Down
Loading

0 comments on commit 39338bc

Please sign in to comment.