From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from fg-out-1718.google.com (fg-out-1718.google.com [72.14.220.157]) by ozlabs.org (Postfix) with ESMTP id 59F6EDDDE7 for ; Mon, 29 Sep 2008 19:24:38 +1000 (EST) Received: by fg-out-1718.google.com with SMTP id d23so1490195fga.39 for ; Mon, 29 Sep 2008 02:24:36 -0700 (PDT) Date: Mon, 29 Sep 2008 11:24:33 +0200 Message-ID: From: Vitaly Mayatskikh To: linuxppc-dev@ozlabs.org Subject: Re: take in count O_NONBLOCK flag for rtas log In-Reply-To: References: MIME-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Content-Type: text/plain; charset=US-ASCII Cc: Paul Mackerras List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , rtas_log_read() doesn't check file flags for O_NONBLOCK and blocks non-blocking reader of /proc/ppc64/rtas/error_log if there's no data available. Patch makes sure that non-blocking reader will never blocks. Also rtas_log_read() returns now with ENODATA to prevent suspending of process in wait_event_interruptible() when logging facility was switched off and log is already empty. Acked-by: David Howells Signed-off-by: Vitaly Mayatskikh diff --git a/arch/powerpc/platforms/pseries/rtasd.c b/arch/powerpc/platforms/pseries/rtasd.c index c9ffd8c..4f76e3b 100644 --- a/arch/powerpc/platforms/pseries/rtasd.c +++ b/arch/powerpc/platforms/pseries/rtasd.c @@ -295,19 +295,29 @@ static ssize_t rtas_log_read(struct file * file, char __user * buf, if (!tmp) return -ENOMEM; - spin_lock_irqsave(&rtasd_log_lock, s); /* if it's 0, then we know we got the last one (the one in NVRAM) */ - if (rtas_log_size == 0 && logging_enabled) - nvram_clear_error_log(); - spin_unlock_irqrestore(&rtasd_log_lock, s); + while (rtas_log_size == 0) { + if (file->f_flags & O_NONBLOCK) { + spin_unlock_irqrestore(&rtasd_log_lock, s); + error = -EAGAIN; + goto out; + } + if (!logging_enabled) { + spin_unlock_irqrestore(&rtasd_log_lock, s); + error = -ENODATA; + goto out; + } + nvram_clear_error_log(); - error = wait_event_interruptible(rtas_log_wait, rtas_log_size); - if (error) - goto out; + spin_unlock_irqrestore(&rtasd_log_lock, s); + error = wait_event_interruptible(rtas_log_wait, rtas_log_size); + if (error) + goto out; + spin_lock_irqsave(&rtasd_log_lock, s); + } - spin_lock_irqsave(&rtasd_log_lock, s); offset = rtas_error_log_buffer_max * (rtas_log_start & LOG_NUMBER_MASK); memcpy(tmp, &rtas_log_buf[offset], count); -- wbr, Vitaly