VirtualBox

Changeset 77731 in vbox for trunk/src/VBox/Additions/linux


Ignore:
Timestamp:
Mar 15, 2019 10:32:02 PM (6 years ago)
Author:
vboxsync
Message:

linux/vboxsf: BDI_CAP_STRICTLIMIT causes trouble with linux 3.16 / debian 8 (amd64), so don't set it for now. Process just hung once we produced too many dirty pages. Seems some throttling logic or similar doesn't quiet work. Only 4.19+ has it enabled for now. bugref:9172

Location:
trunk/src/VBox/Additions/linux/sharedfolders
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/linux/sharedfolders/regops.c

    r77710 r77731  
    5757#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0)
    5858# define iter_is_iovec(a_pIter) ( !((a_pIter)->type & (ITER_KVEC | ITER_BVEC)) )
     59#endif
     60
     61#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0)
     62# define vm_fault_t int
    5963#endif
    6064
     
    22812285
    22822286
     2287#ifdef SFLOG_ENABLED
     2288/*
     2289 * This is just for logging page faults and such.
     2290 */
     2291
     2292/** Pointer to the ops generic_file_mmap returns the first time it's called. */
     2293static struct vm_operations_struct const *g_pGenericFileVmOps = NULL;
     2294/** Merge of g_LoggingVmOpsTemplate and g_pGenericFileVmOps. */
     2295static struct vm_operations_struct        g_LoggingVmOps;
     2296
     2297
     2298/* Generic page fault callback: */
     2299# if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
     2300static vm_fault_t vbsf_vmlog_fault(struct vm_fault *vmf)
     2301{
     2302    vm_fault_t rc;
     2303    SFLOGFLOW(("vbsf_vmlog_fault: vmf=%p flags=%#x addr=%p\n", vmf, vmf->flags, vmf->address));
     2304    rc = g_pGenericFileVmOps->fault(vmf);
     2305    SFLOGFLOW(("vbsf_vmlog_fault: returns %d\n", rc));
     2306    return rc;
     2307}
     2308# elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23)
     2309static int vbsf_vmlog_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
     2310{
     2311    int rc;
     2312#  if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)
     2313    SFLOGFLOW(("vbsf_vmlog_fault: vma=%p vmf=%p flags=%#x addr=%p\n", vma, vmf, vmf->flags, vmf->address));
     2314#  else
     2315    SFLOGFLOW(("vbsf_vmlog_fault: vma=%p vmf=%p flags=%#x addr=%p\n", vma, vmf, vmf->flags, vmf->virtual_address));
     2316#  endif
     2317    rc = g_pGenericFileVmOps->fault(vma, vmf);
     2318    SFLOGFLOW(("vbsf_vmlog_fault: returns %d\n", rc));
     2319    return rc;
     2320}
     2321# endif
     2322
     2323
     2324/* Special/generic page fault handler: */
     2325# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
     2326# elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 1)
     2327static struct page *vbsf_vmlog_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
     2328{
     2329    struct page *page;
     2330    SFLOGFLOW(("vbsf_vmlog_nopage: vma=%p address=%p type=%p:{%#x}\n", vma, address, type, type ? *type : 0));
     2331    page = g_pGenericFileVmOps->nopage(vma, address, type);
     2332    SFLOGFLOW(("vbsf_vmlog_nopage: returns %p\n", page));
     2333    return page;
     2334}
     2335# else
     2336static struct page *vbsf_vmlog_nopage(struct vm_area_struct *vma, unsigned long address, int write_access_or_unused)
     2337{
     2338    struct page *page;
     2339    SFLOGFLOW(("vbsf_vmlog_nopage: vma=%p address=%p wau=%d\n", vma, address, write_access_or_unused));
     2340    page = g_pGenericFileVmOps->nopage(vma, address, write_access_or_unused);
     2341    SFLOGFLOW(("vbsf_vmlog_nopage: returns %p\n", page));
     2342    return page;
     2343}
     2344# endif /* < 2.6.26 */
     2345
     2346
     2347/* Special page fault callback for making something writable: */
     2348# if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
     2349static vm_fault_t vbsf_vmlog_page_mkwrite(struct vm_fault *vmf)
     2350{
     2351    vm_fault_t rc;
     2352#  if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)
     2353    SFLOGFLOW(("vbsf_vmlog_page_mkwrite: vmf=%p flags=%#x addr=%p\n", vmf, vmf->flags, vmf->address));
     2354#  else
     2355    SFLOGFLOW(("vbsf_vmlog_page_mkwrite: vmf=%p flags=%#x addr=%p\n", vmf, vmf->flags, vmf->virtual_address));
     2356#  endif
     2357    rc = g_pGenericFileVmOps->page_mkwrite(vmf);
     2358    SFLOGFLOW(("vbsf_vmlog_page_mkwrite: returns %d\n", rc));
     2359    return rc;
     2360}
     2361# elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
     2362static int vbsf_vmlog_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
     2363{
     2364    int rc;
     2365    SFLOGFLOW(("vbsf_vmlog_page_mkwrite: vma=%p vmf=%p flags=%#x addr=%p\n", vma, vmf, vmf->flags, vmf->virtual_address));
     2366    rc = g_pGenericFileVmOps->page_mkwrite(vma, vmf);
     2367    SFLOGFLOW(("vbsf_vmlog_page_mkwrite: returns %d\n", rc));
     2368    return rc;
     2369}
     2370# elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)
     2371static int vbsf_vmlog_page_mkwrite(struct vm_area_struct *vma, struct page *page)
     2372{
     2373    int rc;
     2374    SFLOGFLOW(("vbsf_vmlog_page_mkwrite: vma=%p page=%p\n", vma, page));
     2375    rc = g_pGenericFileVmOps->page_mkwrite(vma, page);
     2376    SFLOGFLOW(("vbsf_vmlog_page_mkwrite: returns %d\n", rc));
     2377    return rc;
     2378}
     2379# endif
     2380
     2381
     2382/* Special page fault callback for mapping pages: */
     2383# if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)
     2384static void vbsf_vmlog_map_pages(struct vm_fault *vmf, pgoff_t start, pgoff_t end)
     2385{
     2386    SFLOGFLOW(("vbsf_vmlog_map_pages: vmf=%p (flags=%#x addr=%p) start=%p end=%p\n", vmf, vmf->flags, vmf->address, start, end));
     2387    g_pGenericFileVmOps->map_pages(vmf, start, end);
     2388    SFLOGFLOW(("vbsf_vmlog_map_pages: returns\n"));
     2389}
     2390# elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)
     2391static void vbsf_vmlog_map_pages(struct fault_env *fenv, pgoff_t start, pgoff_t end)
     2392{
     2393    SFLOGFLOW(("vbsf_vmlog_map_pages: fenv=%p (flags=%#x addr=%p) start=%p end=%p\n", fenv, vmf->flags, vmf->address, start, end));
     2394    g_pGenericFileVmOps->map_pages(fenv, start, end);
     2395    SFLOGFLOW(("vbsf_vmlog_map_pages: returns\n"));
     2396}
     2397# elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)
     2398static void vbsf_vmlog_map_pages(struct vm_area_struct *vma, struct vm_fault *vmf)
     2399{
     2400    SFLOGFLOW(("vbsf_vmlog_map_pages: vma=%p vmf=%p (flags=%#x addr=%p)\n", vma, vmf, vmf->flags, vmf->virtual_address));
     2401    g_pGenericFileVmOps->map_pages(vma, vmf);
     2402    SFLOGFLOW(("vbsf_vmlog_map_pages: returns\n"));
     2403}
     2404# endif
     2405
     2406
     2407/** Overload template. */
     2408static struct vm_operations_struct const g_LoggingVmOpsTemplate = {
     2409# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23)
     2410    .fault = vbsf_vmlog_fault,
     2411# endif
     2412# if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 25)
     2413    .nopage = vbsf_vmlog_nopage,
     2414# endif
     2415# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)
     2416    .page_mkwrite = vbsf_vmlog_page_mkwrite,
     2417# endif
     2418# if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)
     2419    .map_pages = vbsf_vmlog_map_pages,
     2420# endif
     2421};
     2422
     2423/** file_operations::mmap wrapper for logging purposes. */
     2424extern int vbsf_reg_mmap(struct file *file, struct vm_area_struct *vma)
     2425{
     2426    int rc;
     2427    SFLOGFLOW(("vbsf_reg_mmap: file=%p vma=%p\n", file, vma));
     2428    rc = generic_file_mmap(file, vma);
     2429    if (rc == 0) {
     2430        /* Merge the ops and template the first time thru (there's a race here). */
     2431        if (g_pGenericFileVmOps == NULL) {
     2432            uintptr_t const    *puSrc1 = (uintptr_t *)vma->vm_ops;
     2433            uintptr_t const    *puSrc2 = (uintptr_t *)&g_LoggingVmOpsTemplate;
     2434            uintptr_t volatile *puDst  = (uintptr_t *)&g_LoggingVmOps;
     2435            size_t              cbLeft = sizeof(g_LoggingVmOps) / sizeof(*puDst);
     2436            while (cbLeft-- > 0) {
     2437                *puDst = *puSrc2 && *puSrc1 ? *puSrc2 : *puSrc1;
     2438                puSrc1++;
     2439                puSrc2++;
     2440                puDst++;
     2441            }
     2442            g_pGenericFileVmOps = vma->vm_ops;
     2443            vma->vm_ops = &g_LoggingVmOps;
     2444        } else if (g_pGenericFileVmOps == vma->vm_ops)
     2445            vma->vm_ops = &g_LoggingVmOps;
     2446        else
     2447            SFLOGFLOW(("vbsf_reg_mmap: Warning: vm_ops=%p, expected %p!\n", vma->vm_ops, g_pGenericFileVmOps));
     2448    }
     2449    SFLOGFLOW(("vbsf_reg_mmap: returns %d\n", rc));
     2450    return rc;
     2451}
     2452
     2453#endif /* SFLOG_ENABLED */
     2454
     2455
    22832456/**
    22842457 * File operations for regular files.
     
    22932466#endif
    22942467    .release     = vbsf_reg_release,
     2468#ifdef SFLOG_ENABLED
     2469    .mmap        = vbsf_reg_mmap,
     2470#else
    22952471    .mmap        = generic_file_mmap,
     2472#endif
    22962473#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
    22972474# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)
  • trunk/src/VBox/Additions/linux/sharedfolders/vfsmod.c

    r77709 r77731  
    299299#  endif
    300300#  ifdef BDI_CAP_STRICTLIMIT
     301#   if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) /* Trouble with 3.16.x/debian8.  Process stops after dirty page throttling.
     302                                                       * Only tested successfully with 4.19.  Maybe skip altogether? */
    301303                      | BDI_CAP_STRICTLIMIT;
     304#   endif
    302305#  endif
    303306              ;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette