今天处理一个cpu标高的bug,原因:在poll 返回后将error事件当做POLLIN事件处理,fd 一直都在唤醒线程处理,但是rcv的时候没有数据;

unsigned int datagram_poll(struct file *file, struct socket *sock,
poll_table *wait)
{
struct sock *sk = sock->sk;
unsigned int mask; sock_poll_wait(file, sk_sleep(sk), wait);
mask = 0; /* exceptional events? */
if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
mask |= POLLERR;
if (sk->sk_shutdown & RCV_SHUTDOWN)
mask |= POLLRDHUP | POLLIN | POLLRDNORM;
if (sk->sk_shutdown == SHUTDOWN_MASK)
mask |= POLLHUP;
static unsigned int packet_poll(struct file *file, struct socket *sock,
poll_table *wait)
{
struct sock *sk = sock->sk;
struct packet_sock *po = pkt_sk(sk);
unsigned int mask = datagram_poll(file, sock, wait); spin_lock_bh(&sk->sk_receive_queue.lock);
if (po->rx_ring.pg_vec) {
if (!packet_previous_rx_frame(po, &po->rx_ring,
TP_STATUS_KERNEL))
mask |= POLLIN | POLLRDNORM;
}

从代码中可以看到(sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)  只要满足一个条件就会唤醒进程,但是由于sk_error_queue 的数据一直都没有清楚,所以会导致一直唤醒进程。但是mmap-packet读取数据时,又没有数据

那么怎么处理呢?

目前简单的处理方式为:在rcvmsg时 带上MSG_ERRQUEUE  主动收取错误报文

或者

case SO_ERROR:
v.val = -sock_error(sk);
if (v.val == 0)
v.val = xchg(&sk->sk_err_soft, 0);
break; //使用getsockopt 获取错误标志 case IP_RECVERR:
inet->recverr = !!val;
if (!val)
skb_queue_purge(&sk->sk_error_queue);
break; //使用 ip_setsockopt 清除数据

说一说packet poll 错误掩码的一个bug tcp udp packet poll细节有所不同 处理时需要注意的更多相关文章

  1. (转载) socket:10038错误{winSock的一个bug:当closesocket多次错误使用时会导致问题}

    这几天想在一个开源的代码上进行修改,以期研发出一个产品出来.       程序原来是单线程网络程序,需要修改为多线程,修改之后,总是出问题,辅助线程中的recv函数总是运行一阵子之后收到长度为-1的数 ...

  2. 看看poll 事件掩码 --- review代码时发现掩码不分的错误

    事件 描述 是否可作为输入(events) 是否可作为输出(revents) POLLIN 数据可读(包括普通数据&优先数据) 是 是 POLLOUT 数据可写(普通数据&优先数据) ...

  3. dos界面下执行java文件将错误输出到一个文本小技巧

    如果dos下执行java出现错误,把错误记录到一个文档 正确时如图,输出结果为hello,我把String的s改为小写,出现错误,用2>命令输出到error.txt在当前目录就出现了error. ...

  4. 未指定的错误,发生了一个 Oracle 错误,但无法从 Oracle 中检索错误信息。数据类型不被支持。

    未指定的错误,发生了一个 Oracle 错误,但无法从 Oracle 中检索错误信息.数据类型不被支持. 博客分类: 雅芳生涯 .Net VB C# OracleMicrosoftSecurity  ...

  5. mysql错误:Can’t create TCP/IP socket (10106) 解决方法

    错误描述 “mysql错误:Can’t create TCP/IP socket (10106)”,目测是socket端口被占用的原因,然后在打开tomcat,报的错误中也包含了“socket”,再一 ...

  6. linux下将编译错误输出到一个文本文件

    linux下将编译错误输出到一个文本文件 command > filename 把把标准输出重定向到一个新文件中 command > > filename 把把标准输出重定向到一个文 ...

  7. 编程中易犯错误汇总:一个综合案例.md

    # 11编程中易犯错误汇总:一个综合案例 在上一篇文章中,我们学习了如何区分好的代码与坏的代码,如何写好代码.所谓光说不练假把式,在这篇文章中,我们就做一件事——一起来写代码.首先,我会先列出问题,然 ...

  8. Linux网络通信编程(套接字模型TCP\UDP与IO多路复用模型select\poll\epoll)

    Linux下测试代码: http://www.linuxhowtos.org/C_C++/socket.htm TCP模型 //TCPClient.c #include<string.h> ...

  9. Win10 UWP系列:关于错误 0x80073CF9及一个小bug的解决

    最近一直在开发XX的uwp版本,也是边摸索边做,最近遇到几个比较奇怪的问题,记录于此. 1.项目可用部署到PC,但无法部署到手机,提示以下错误: 错误 : DEP0001 : 意外错误: Instal ...

随机推荐

  1. (转载)跟Classic ARM 处理器说拜拜——Atmel SAMA5D3 Xplained开发板评测

    2014 年 4 月 10 日 时间: 下午 3:15 作者: 幸得安然 电子产业的蓬勃发展带来了史无前例的生活.生产大跃进,但是,人们在享受发展喜悦的同时又不得不面临现实现状的囧境--在以移动电子设 ...

  2. 多测师讲解python _re模块_高级讲师肖sir

    import re# 一.常用方法:# match():从头匹配# search():从整个文本搜索# findall():找到所有符合的# split():分割# sub():替换# group() ...

  3. c# 误区系列(一)

    前言 整理很早以前认为的一些误区,准备整理一个系列.新手可以看下,然后大佬指点一下是否哪些地方错了. 正文 值类型存在栈上,引用类型存在堆上 很多人认为用这句话来解释值类型和栈类型的区别,甚至有些文章 ...

  4. spring 源码构建

    参照这里(按照下面链接一路绿灯) https://blog.csdn.net/chengqiuming/article/details/102331033 1.安装配置gradle环境 1).  配置 ...

  5. day45 Pyhton 数据库Mysql 02

    一.前期回顾 数据库 mysql的安装 配置环境 为什么要用数据库? 稳定性 一致性 并发 存取数据效率高 数据库的分类 关系型数据库 mysql oracle sqlserver 非关系型数据库 r ...

  6. PO模式学习笔记

    框架: 1.PO模式应用(测试对象和测试用例分离)(写到简历中) 2.引入ddt 3.深入分层:测试数据分离 4.遵循原则:测试用例的独立性 5.深入分层:元素定位分离 6.框架优化:提取basepa ...

  7. trade可撤销贪心正确性证明

    鉴于tarde这道题正解过于好写,导致我对这个诡异的贪心的正确性产生了疑问,所以花了2h的时间与同机房神犇M-Blanca,Midoria7,goote~进行讨论,最后与goote~犇犇各得出了一个正 ...

  8. 2020年sublime text3可用的注册码

    2020年sublime text3可用的注册码 最近终于找到可以用的sublime text3注册码了,仅供各位同学交流学习使用.用完请删除,购买正版! ----- BEGIN LICENSE -- ...

  9. virtualbox 网络地址转换(NAT)

    网络地址转换 虚拟机可以访问主机 通过主机请求外网 但是主机不能请求虚拟机 所以要配置端口转发才行 host-only模式下 不同网段的不同虚拟机也可以互相ping通  比如 192.168.33.1 ...

  10. C++ Primer第5版 第三章课后练习

    练习3.1 #include <iostream> using namespace std; int main() { int sum = 0, val = 50; while (val ...