The bug fixed by this commit is causing chrome processes to get stuck
spinning at 100% CPU on my FreeBSD 10.1-RELEASE laptop -- chrome is
trying to read the kern.proc.pid.# sysctl (I think in order to get the
status of a crashed rendering process) and it's going into an infinite
ERESTART loop.

Is anyone else seeing the 100%-CPU-usage chrome problem?  It seems to
be triggered by a crashing chrome rendering process, and I don't know
what's causing that, so it's possible that this isn't affecting many
other people.

Konstantin, if this turns out to be affecting a lot of people, do you
think we could get an errata notice for this?

Colin Percival

On 10/05/14 10:36, Konstantin Belousov wrote:
> Author: kib
> Date: Sun Oct  5 17:35:59 2014
> New Revision: 272566
> URL: https://svnweb.freebsd.org/changeset/base/272566
> 
> Log:
>   On error, sbuf_bcat() returns -1.  Some callers returned this -1 to
>   the upper layers, which interpret it as errno value, which happens to
>   be ERESTART.  The result was spurious restarts of the sysctls in loop,
>   e.g. kern.proc.proc, instead of returning ENOMEM to caller.
>   
>   Convert -1 from sbuf_bcat() to ENOMEM, when returning to the callers
>   expecting errno.
>   
>   In collaboration with:      pho
>   Sponsored by:       The FreeBSD Foundation (kib)
>   MFC after:  1 week
> 
> Modified:
>   head/sys/kern/kern_descrip.c
>   head/sys/kern/kern_proc.c
> 
> Modified: head/sys/kern/kern_descrip.c
> ==============================================================================
> --- head/sys/kern/kern_descrip.c      Sun Oct  5 11:16:16 2014        
> (r272565)
> +++ head/sys/kern/kern_descrip.c      Sun Oct  5 17:35:59 2014        
> (r272566)
> @@ -3097,7 +3097,7 @@ export_kinfo_to_sb(struct export_fd_buf 
>               }
>               efbuf->remainder -= kif->kf_structsize;
>       }
> -     return (sbuf_bcat(efbuf->sb, kif, kif->kf_structsize));
> +     return (sbuf_bcat(efbuf->sb, kif, kif->kf_structsize) == 0 ? 0 : 
> ENOMEM);
>  }
>  
>  static int
> 
> Modified: head/sys/kern/kern_proc.c
> ==============================================================================
> --- head/sys/kern/kern_proc.c Sun Oct  5 11:16:16 2014        (r272565)
> +++ head/sys/kern/kern_proc.c Sun Oct  5 17:35:59 2014        (r272566)
> @@ -1208,21 +1208,25 @@ kern_proc_out(struct proc *p, struct sbu
>  #ifdef COMPAT_FREEBSD32
>               if ((flags & KERN_PROC_MASK32) != 0) {
>                       freebsd32_kinfo_proc_out(&ki, &ki32);
> -                     error = sbuf_bcat(sb, &ki32, sizeof(ki32));
> +                     if (sbuf_bcat(sb, &ki32, sizeof(ki32)) != 0)
> +                             error = ENOMEM;
>               } else
>  #endif
> -                     error = sbuf_bcat(sb, &ki, sizeof(ki));
> +                     if (sbuf_bcat(sb, &ki, sizeof(ki)) != 0)
> +                             error = ENOMEM;
>       } else {
>               FOREACH_THREAD_IN_PROC(p, td) {
>                       fill_kinfo_thread(td, &ki, 1);
>  #ifdef COMPAT_FREEBSD32
>                       if ((flags & KERN_PROC_MASK32) != 0) {
>                               freebsd32_kinfo_proc_out(&ki, &ki32);
> -                             error = sbuf_bcat(sb, &ki32, sizeof(ki32));
> +                             if (sbuf_bcat(sb, &ki32, sizeof(ki32)) != 0)
> +                                     error = ENOMEM;
>                       } else
>  #endif
> -                             error = sbuf_bcat(sb, &ki, sizeof(ki));
> -                     if (error)
> +                             if (sbuf_bcat(sb, &ki, sizeof(ki)) != 0)
> +                                     error = ENOMEM;
> +                     if (error != 0)
>                               break;
>               }
>       }
> @@ -1777,7 +1781,8 @@ proc_getauxv(struct thread *td, struct p
>               else
>  #endif
>                       size = vsize * sizeof(Elf_Auxinfo);
> -             error = sbuf_bcat(sb, auxv, size);
> +             if (sbuf_bcat(sb, auxv, size) != 0)
> +                     error = ENOMEM;
>               free(auxv, M_TEMP);
>       }
>       return (error);
> @@ -2363,9 +2368,10 @@ kern_proc_vmmap_out(struct proc *p, stru
>                   strlen(kve->kve_path) + 1;
>               kve->kve_structsize = roundup(kve->kve_structsize,
>                   sizeof(uint64_t));
> -             error = sbuf_bcat(sb, kve, kve->kve_structsize);
> +             if (sbuf_bcat(sb, kve, kve->kve_structsize) != 0)
> +                     error = ENOMEM;
>               vm_map_lock_read(map);
> -             if (error)
> +             if (error != 0)
>                       break;
>               if (last_timestamp != map->timestamp) {
>                       vm_map_lookup_entry(map, addr - 1, &tmp_entry);
> 
> 
> 

-- 
Colin Percival
Security Officer Emeritus, FreeBSD | The power to serve
Founder, Tarsnap | www.tarsnap.com | Online backups for the truly paranoid
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-chromium
To unsubscribe, send any mail to "[email protected]"

Reply via email to