= &init_struct_pid) { retval = -ENOMEM; pid = alloc_pid(p->nsproxy->pid_ns); if (! 大家注意这段代码的细节:无论 alloc_pid 返回的是何种类型的失败,其错误类型都写死的返回 -ENOMEM。。。 为了方便大家理解,我单独把这段逻辑再展示一遍。 = &init_struct_pid) { retval = -ENOMEM; pid = alloc_pid(p->nsproxy->pid_ns); if (! (retval = -ENOMEM),只要 alloc_pid 返回的不正确,都是将 ENOMEM 这个错误返回给上层。 它的意思是“ENOMEM不是最明显的选择,尤其是对于 pid 创建失败的情况下。但是,ENOMEM 是我们长期暴露给用户空间的东西。
rb_parent, and uf */ if (munmap_vma_range(mm, addr, len, &prev, &rb_link, &rb_parent, uf)) return -ENOMEM may_expand_vm(mm, flags, len >> PAGE_SHIFT)) return -ENOMEM; if (mm->map_count > sysctl_max_map_count ) return -ENOMEM; if (security_vm_enough_memory_mm(mm, len >> PAGE_SHIFT)) return -ENOMEM; vma) { vm_unacct_memory(len >> PAGE_SHIFT); return -ENOMEM; } vma_set_anonymous(vma);
may_expand_vm(mm, len >> PAGE_SHIFT)) return -ENOMEM; if (mm->map_count > sysctl_max_map_count) return -ENOMEM; if (security_vm_enough_memory_mm(mm, len >> PAGE_SHIFT)) return -ENOMEM; /* Can vma) { vm_unacct_memory(len >> PAGE_SHIFT); return -ENOMEM; } INIT_LIST_HEAD(&vma->anon_vma_chain = -ENOMEM); info.flags = 0; info.low_limit = mm->mmap_base; info.high_limit = TASK_SIZE; addr 返回0表示查找最合适插入的节点,返回-ENOMEM表示和现有的VMA重叠,这时会调用do_munmap()函数来释放这段重叠的空间。
may_expand_vm(mm, vm_flags, (len >> PAGE_SHIFT) - nr_pages)) return -ENOMEM; } 源码路径 : linux- addr + len, &prev, &rb_link, &rb_parent)) { if (do_munmap(mm, addr, len, uf)) return -ENOMEM may_expand_vm(mm, vm_flags, (len >> PAGE_SHIFT) - nr_pages)) return -ENOMEM; } /* Clear old addr + len, &prev, &rb_link, &rb_parent)) { if (do_munmap(mm, addr, len, uf)) return -ENOMEM vma) { error = -ENOMEM; goto unacct_error; } vma->vm_mm = mm; vma->vm_start = addr; vma->vm_end
XXX_NAME)) { dev_err(p_device_info->dev, "xxx_map_mem request_mem_region failed\n"); return -ENOMEM Unable to map registers\n"); release_mem_region(p_device_info->phy_base, XXX_REG_SPACE); return -ENOMEM
bus_kset) return -ENOMEM; system_kset = kset_create_and_add("system", NULL, &devices_kset->kobj); system_kset) return -ENOMEM; return 0; } 通过上述的操作将在sysfs下创建了一个名字为"bus"的目录,同时也会在/sys/devices/下创建一个名字为 priv) return -ENOMEM; priv->bus = bus; //设置bus指针 bus->p = priv->drivers_kset) { retval = -ENOMEM; goto bus_drivers_fail; } INIT_LIST_HEAD(&priv->interfaces dev) { err = -ENOMEM; goto err_dev; } err = dev_set_name(dev, "%s", subsys->name); if (err <
priv) return -ENOMEM; priv->bus = bus; bus->p = priv; BLOCKING_INIT_NOTIFIER_HEAD priv->devices_kset) { retval = -ENOMEM; goto bus_devices_fail; } priv->drivers_kset priv->drivers_kset) { retval = -ENOMEM; goto bus_drivers_fail; } INIT_LIST_HEAD priv) { error = -ENOMEM; goto out_put_bus; } klist_init(&priv->klist_devices,
返回值为初始化成功LOS_OK还是失败LOS_ENOMEM。 NULL) { processCB->processStatus = OS_PROCESS_FLAG_UNUSED; return LOS_ENOMEM m_aucSysMem1, sizeof(OsCpupBase)); if (processCB->processCpup == NULL) { return LOS_ENOMEM = LOS_OK) { return LOS_ENOMEM; } #endif⑺ #ifdef LOSCFG_SECURITY_CAPABILITY = LOS_OK) { return LOS_ENOMEM; } return LOS_OK; }1.2 进程控制块初始化恢复函数OsDeInitPCB
to_of_device(dev); if (add_uevent_var(env, “OF_NAME=%s”, ofdev->dev.of_node->name)) return -ENOMEM ; if (add_uevent_var(env, “OF_TYPE=%s”, ofdev->dev.of_node->type)) return -ENOMEM; 0) { if (add_uevent_var(env, “OF_COMPATIBLE_%d=%s”, seen, compat)) return -ENOMEM seen++; } if (add_uevent_var(env, “OF_COMPATIBLE_N=%d”, seen)) return -ENOMEM modalias is trickier, we add it in 2 steps */ if (add_uevent_var(env, “MODALIAS=”)) return -ENOMEM
pgd) return -ENOMEM; p4d = vmemmap_p4d_populate(pgd, addr, node); if (! p4d) return -ENOMEM; pud = vmemmap_pud_populate(p4d, addr, node); if (! pud) return -ENOMEM; pmd = vmemmap_pmd_populate(pud, addr, node); if (! pmd) return -ENOMEM; pte = vmemmap_pte_populate(pmd, addr, node); if (! pte) return -ENOMEM; vmemmap_verify(pte, node, addr, addr + PAGE_SIZE); } return 0; }
heap) return ERR_PTR(-ENOMEM); heap->ops = &kmalloc_ops; heap->type = ION_HEAP_TYPE_SYSTEM_CONTIG page) return -ENOMEM; //将申请到的连续内存页分割成一页页 split_page(page, order); //由于在分配时可能多分配,因此需要将多余的page table) { ret = -ENOMEM; goto free_pages; } //由于是连续的内存,因此只需要申请一个scatterlist ret = sg_alloc_table
\n") return libavutil.ENOMEM } /* Create the abuffer filter; * it will be used for feeding \n") return -libavutil.ENOMEM } /* Set the filter options through the AVOptions API. */ libavutil.AvGetChannelLayoutString \n") return -libavutil.ENOMEM } /* A different way of passing the options is as key/value pairs \n") return -libavutil.ENOMEM } /* A third way of passing the options is in a string of the \n") return -libavutil.ENOMEM } /* This filter takes no options. */ err = abuffersink_ctx.AvfilterInitStr
明确错误码返回:不再通过返回NULL隐式表示错误,而是通过errno_t类型返回具体错误码(如EINVAL表示参数无效,ENOMEM表示内存不足),便于精准定位问题。 返回值:errno_t:错误码类型(本质是整数),返回0表示成功,非 0 表示失败(如EINVAL参数无效、ENOMEM内存不足)。 2. SIZE_MAX >> 1) // 最大安全分配值(通常为SIZE_MAX/2,避免溢出) #define EINVAL 22 // 错误码:参数无效 #define ENOMEM ); return ENOMEM; } // 第六步:内存清零(复用系统优化,如新页自动清零) // 注:malloc_s()若分配新页已清零,此处可省略;若为旧页则需 = calloc_s(num, size, &ptr); if (err == 0) return ptr; // 若为内存不足,尝试减小一半大小重试 if (err == ENOMEM
msq)) return -ENOMEM; ... } 这个代码在早期的内核里面是(比如v4.0-rc7/source/ipc/msg.c): static int newque(struct msq) return -ENOMEM; ... } 看起来是用的这个函数申请内存: ipc_rcu_alloc(sizeof(*msq)) 那么这个ipc_rc_alloc()是怎么回事呢
\n")return libavutil.ENOMEM}/* Create the abuffer filter; * it will be used for feeding the data into \n")return -libavutil.ENOMEM}/* Set the filter options through the AVOptions API. \n")return -libavutil.ENOMEM}/* A different way of passing the options is as key/value pairs in a * dictionary \n")return -libavutil.ENOMEM}/* A third way of passing the options is in a string of the form * key1= \n")return -libavutil.ENOMEM}/* This filter takes no options.
2.3 返回值:成功与失败的 "信号弹" 加载函数的返回值有严格规定: 返回 0:表示初始化成功,模块顺利加载 返回负数:表示失败,这个负数必须是内核标准错误码(如-ENOMEM表示内存不足,-EINVAL buf) { printk(KERN_ERR "内存申请失败\n"); return -ENOMEM; // 只需要返回,还没申请其他资源 } // resA) { ret = -ENOMEM; goto fail_A; } // 申请资源B ret = alloc_resourceB(resA 但系统内存充足 现象:加载函数申请内存失败,返回-ENOMEM,但free命令显示内存很多。 buffer) { printk(KERN_ERR "内存申请失败(%d字节)\n", BUF_SIZE); return -ENOMEM; // 还没申请其他资源,直接返回
= iov->nres) {pci_err(dev, "not enough MMIO resources for SR-IOV\n");return -ENOMEM;}/* vf应该出现的bus号 , "can't enable %d VFs (bus %02x out of range of %pR)\n",nr_virtfn, bus, &dev->bus->busn_res);return -ENOMEM ;}if (pci_enable_resources(dev, bars)) {pci_err(dev, "SR-IOV: IOV BARS not allocated\n");return -ENOMEM bus) {rc = -ENOMEM;goto failed;}/* 新建总线和pci设备 ,设置vf归属关系和基本pci属性*/virtfn = pci_iov_scan_device(dev, id bus) {rc = -ENOMEM;goto failed;}/* 新建总线和pci设备 ,设置vf归属关系和基本pci属性*/virtfn = pci_iov_scan_device(dev, id
keypad_data) { dev_err(&pdev->dev, "keypad_data memory allocation failed\n"); return -ENOMEM; } keypad_data->base) { dev_err(&pdev->dev, "can't ioremap mem resource\n"); error = -ENOMEM; goto input_dev) { error = -ENOMEM; goto err_pm_put_sync; } input_dev->name = pdev->name; input_dev keypad_data->keymap) { dev_err(&pdev->dev, "Not enough memory for keymap\n"); error = -ENOMEM; keymap) { dev_err(input_dev->dev.parent, "Unable to allocate memory for keymap"); return -ENOMEM
所指的共享内存已经删除 ENOSPC:超过了系统允许建立的共享内存的最大值(SHMALL) ENOENT:参数key所指的共享内存不存在,而参数shmflg未设IPC_CREAT位 EACCES:没有权限 ENOMEM 后该子进程与已连接的共享内存地址自动脱离(detach);进程结束后,已连接的共享内存地址会自动脱离(detach) 有以下几种错误 EACCES:无权限以指定方式连接共享内存 EINVAL:无效的参数shmid或shmaddr ENOMEM 有以下几种错误 EACCESS:没有权限 EEXIST:信号量集已经存在,无法创建 EIDRM:信号量集已经删除 ENOENT:信号量集不存在,同时semflg没有设置IPC_CREAT标志 ENOMEM IPC_NOWAIT,但操作不能继续进行 EFAULT:sops指向的地址无效 EIDRM:信号量集已经删除 EINTR:当睡眠时接收到其他信号 EINVAL:信号量集不存在,或者semid无效 ENOMEM
msq)) return -ENOMEM; ... } 这个代码在早期的内核里面是(比如v4.0-rc7/source/ipc/msg.c): static int newque(struct msq) return -ENOMEM; ... } 看起来是用的这个函数申请内存: ipc_rcu_alloc(sizeof(*msq)) 那么这个ipc_rc_alloc()是怎么回事呢