• 说一说packet poll 错误掩码的一个bug tcp udp packet poll细节有所不同 处理时需要注意


    今天处理一个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  清除数据
  • 相关阅读:
    nginx 安装教程
    php 安装教程
    第一个AWK程序的尝试
    memcached-tool 工具
    java数据库 DBHelper
    Innodb的三大关健特性
    我遇到的一个ClassNotFoundException问题
    storm学习初步
    再探 jQuery
    简单聊一聊正则表达式中的贪婪匹配和非贪婪匹配
  • 原文地址:https://www.cnblogs.com/codestack/p/12845372.html
Copyright © 2020-2023  润新知