* [PATCH] memory ordering in __kfifo primitives @ 2006-08-10 0:18 Paul E. McKenney 2006-08-10 0:29 ` Andrew Morton 2006-08-10 0:33 ` Paul E. McKenney 0 siblings, 2 replies; 14+ messages in thread From: Paul E. McKenney @ 2006-08-10 0:18 UTC (permalink / raw) To: stelian; +Cc: linux-kernel, akpm, paulus, anton, open-iscsi, pradeep, mashirle Hello! Both __kfifo_put() and __kfifo_get() have header comments stating that if there is but one concurrent reader and one concurrent writer, locking is not necessary. This is almost the case, but a couple of memory barriers are needed. Another option would be to change the header comments to remove the bit about locking not being needed, and to change the those callers who currently don't use locking to add the required locking. The attachment analyzes this approach, but the patch below seems simpler. Signed-off-by: Paul E. McKenney <paulmck@us.ibm.com> --- kfifo.c | 4 ++++ 1 files changed, 4 insertions(+) diff -urpNa -X dontdiff linux-2.6.18-rc2/kernel/kfifo.c linux-2.6.18-rc2-kfifo/kernel/kfifo.c --- linux-2.6.18-rc2/kernel/kfifo.c 2006-07-15 14:53:08.000000000 -0700 +++ linux-2.6.18-rc2-kfifo/kernel/kfifo.c 2006-08-09 14:01:53.000000000 -0700 @@ -129,6 +129,8 @@ unsigned int __kfifo_put(struct kfifo *f /* then put the rest (if any) at the beginning of the buffer */ memcpy(fifo->buffer, buffer + l, len - l); + smp_wmb(); + fifo->in += len; return len; @@ -161,6 +163,8 @@ unsigned int __kfifo_get(struct kfifo *f /* then get the rest (if any) from the beginning of the buffer */ memcpy(buffer + l, fifo->buffer, len - l); + smp_mb(); + fifo->out += len; return len; ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] memory ordering in __kfifo primitives 2006-08-10 0:18 [PATCH] memory ordering in __kfifo primitives Paul E. McKenney @ 2006-08-10 0:29 ` Andrew Morton 2006-08-10 1:01 ` Paul E. McKenney 2006-08-10 0:33 ` Paul E. McKenney 1 sibling, 1 reply; 14+ messages in thread From: Andrew Morton @ 2006-08-10 0:29 UTC (permalink / raw) To: paulmck; +Cc: stelian, linux-kernel, paulus, anton, open-iscsi, pradeep, mashirle On Wed, 9 Aug 2006 17:18:23 -0700 "Paul E. McKenney" <paulmck@us.ibm.com> wrote: > @@ -129,6 +129,8 @@ unsigned int __kfifo_put(struct kfifo *f > /* then put the rest (if any) at the beginning of the buffer */ > memcpy(fifo->buffer, buffer + l, len - l); > > + smp_wmb(); > + > fifo->in += len; > > return len; > @@ -161,6 +163,8 @@ unsigned int __kfifo_get(struct kfifo *f > /* then get the rest (if any) from the beginning of the buffer */ > memcpy(buffer + l, fifo->buffer, len - l); > > + smp_mb(); > + > fifo->out += len; > > return len; When adding barriers, please also add a little comment explaining what the barrier is protecting us from. Often it's fairly obvious, but sometimes it is not, and in both cases it is still useful to communicate the programmer's intent in this way. Thanks. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] memory ordering in __kfifo primitives 2006-08-10 0:29 ` Andrew Morton @ 2006-08-10 1:01 ` Paul E. McKenney 0 siblings, 0 replies; 14+ messages in thread From: Paul E. McKenney @ 2006-08-10 1:01 UTC (permalink / raw) To: Andrew Morton Cc: stelian, linux-kernel, paulus, anton, open-iscsi, pradeep, mashirle On Wed, Aug 09, 2006 at 05:29:10PM -0700, Andrew Morton wrote: > On Wed, 9 Aug 2006 17:18:23 -0700 > "Paul E. McKenney" <paulmck@us.ibm.com> wrote: > > > @@ -129,6 +129,8 @@ unsigned int __kfifo_put(struct kfifo *f > > /* then put the rest (if any) at the beginning of the buffer */ > > memcpy(fifo->buffer, buffer + l, len - l); > > > > + smp_wmb(); > > + > > fifo->in += len; > > > > return len; > > @@ -161,6 +163,8 @@ unsigned int __kfifo_get(struct kfifo *f > > /* then get the rest (if any) from the beginning of the buffer */ > > memcpy(buffer + l, fifo->buffer, len - l); > > > > + smp_mb(); > > + > > fifo->out += len; > > > > return len; > > When adding barriers, please also add a little comment explaining what the > barrier is protecting us from. > > Often it's fairly obvious, but sometimes it is not, and in both cases it is still > useful to communicate the programmer's intent in this way. I certainly cannot claim that it was obvious in this case, as the act of adding the comments caused me to realize that I had added only two of the four memory barriers that are required. :-/ Updated patch below. Signed-off-by: Paul E. McKenney <paulmck@us.ibm.com> --- kfifo.c | 28 ++++++++++++++++++++++++++++ 1 files changed, 28 insertions(+) diff -urpNa -X dontdiff linux-2.6.18-rc2/kernel/kfifo.c linux-2.6.18-rc2-kfifo/kernel/kfifo.c --- linux-2.6.18-rc2/kernel/kfifo.c 2006-07-15 14:53:08.000000000 -0700 +++ linux-2.6.18-rc2-kfifo/kernel/kfifo.c 2006-08-09 17:45:41.000000000 -0700 @@ -122,6 +122,13 @@ unsigned int __kfifo_put(struct kfifo *f len = min(len, fifo->size - fifo->in + fifo->out); + /* + * Ensure that we sample the fifo->out index -before- we + * start putting bytes into the kfifo. + */ + + smp_mb(); + /* first put the data starting from fifo->in to buffer end */ l = min(len, fifo->size - (fifo->in & (fifo->size - 1))); memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), buffer, l); @@ -129,6 +136,13 @@ unsigned int __kfifo_put(struct kfifo *f /* then put the rest (if any) at the beginning of the buffer */ memcpy(fifo->buffer, buffer + l, len - l); + /* + * Ensure that we add the bytes to the kfifo -before- + * we update the fifo->in index. + */ + + smp_wmb(); + fifo->in += len; return len; @@ -154,6 +168,13 @@ unsigned int __kfifo_get(struct kfifo *f len = min(len, fifo->in - fifo->out); + /* + * Ensure that we sample the fifo->in index -before- we + * start removing bytes from the kfifo. + */ + + smp_rmb(); + /* first get the data from fifo->out until the end of the buffer */ l = min(len, fifo->size - (fifo->out & (fifo->size - 1))); memcpy(buffer, fifo->buffer + (fifo->out & (fifo->size - 1)), l); @@ -161,6 +182,13 @@ unsigned int __kfifo_get(struct kfifo *f /* then get the rest (if any) from the beginning of the buffer */ memcpy(buffer + l, fifo->buffer, len - l); + /* + * Ensure that we remove the bytes from the kfifo -before- + * we update the fifo->out index. + */ + + smp_mb(); + fifo->out += len; return len; ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] memory ordering in __kfifo primitives 2006-08-10 0:18 [PATCH] memory ordering in __kfifo primitives Paul E. McKenney 2006-08-10 0:29 ` Andrew Morton @ 2006-08-10 0:33 ` Paul E. McKenney 2006-08-10 5:48 ` Mike Christie 1 sibling, 1 reply; 14+ messages in thread From: Paul E. McKenney @ 2006-08-10 0:33 UTC (permalink / raw) To: stelian Cc: linux-kernel, akpm, paulus, anton, open-iscsi, pradeep, mashirle, michaelc [-- Attachment #1: Type: text/plain, Size: 1976 bytes --] OK, it appears that we are even. I forgot to attach the promised analysis of the callers to __kfifo_put() and __kfifo_get(), and the open-iscsi@googlegroups.com email address listed as maintainer in drivers/scsi/libiscsi.c bounces complaining that, as a non-member, I am not allowed to send it email. ;-) Anyway, this time the analysis really is attached, sorry for my confusion! Could someone please let the guys on open-iscsi@googlegroups.com know that they should take a look at this? Thanx, Paul On Wed, Aug 09, 2006 at 05:18:23PM -0700, Paul E. McKenney wrote: > Hello! > > Both __kfifo_put() and __kfifo_get() have header comments stating > that if there is but one concurrent reader and one concurrent writer, > locking is not necessary. This is almost the case, but a couple of > memory barriers are needed. Another option would be to change the > header comments to remove the bit about locking not being needed, and > to change the those callers who currently don't use locking to add > the required locking. The attachment analyzes this approach, but the > patch below seems simpler. > > Signed-off-by: Paul E. McKenney <paulmck@us.ibm.com> > --- > > kfifo.c | 4 ++++ > 1 files changed, 4 insertions(+) > > diff -urpNa -X dontdiff linux-2.6.18-rc2/kernel/kfifo.c linux-2.6.18-rc2-kfifo/kernel/kfifo.c > --- linux-2.6.18-rc2/kernel/kfifo.c 2006-07-15 14:53:08.000000000 -0700 > +++ linux-2.6.18-rc2-kfifo/kernel/kfifo.c 2006-08-09 14:01:53.000000000 -0700 > @@ -129,6 +129,8 @@ unsigned int __kfifo_put(struct kfifo *f > /* then put the rest (if any) at the beginning of the buffer */ > memcpy(fifo->buffer, buffer + l, len - l); > > + smp_wmb(); > + > fifo->in += len; > > return len; > @@ -161,6 +163,8 @@ unsigned int __kfifo_get(struct kfifo *f > /* then get the rest (if any) from the beginning of the buffer */ > memcpy(buffer + l, fifo->buffer, len - l); > > + smp_mb(); > + > fifo->out += len; > > return len; [-- Attachment #2: kfifo.txt --] [-- Type: text/plain, Size: 6922 bytes --] drivers/scsi/iscsi_tcp.c iscsi_r2t_rsp 377 rc = __kfifo_get(tcp_ctask->r2tpool.queue, (void *)&r2t, sizeof(void *)); Covered by session->lock. drivers/scsi/iscsi_tcp.c handle_xmstate_sol_data 1718 if (__kfifo_get(tcp_ctask->r2tqueue, (void *)&r2t, sizeof(void *))) { Not covered by session->lock. drivers/scsi/iscsi_tcp.c iscsi_tcp_ctask_xmit 1839 __kfifo_get(tcp_ctask->r2tqueue, (void *)&tcp_ctask->r2t, Covered by session->lock. drivers/scsi/iscsi_tcp.c iscsi_tcp_cleanup_ctask 2011 while (__kfifo_get(tcp_ctask->r2tqueue, (void *)&r2t, sizeof(void *))) Covered by session->lock, at least according to the comments. (called by iscsi_tcp_cleanup_ctask(), which is called by things invoking the cleanup_cmd_task function pointer, which is invoked by fail_command(), which has a header comment demanding that session->lock be held by callers. drivers/scsi/libiscsi.c iscsi_data_xmit 556 while (__kfifo_get(conn->immqueue, (void *)&conn->mtask, Not covered by session->lock. drivers/scsi/libiscsi.c iscsi_data_xmit 571 while (__kfifo_get(conn->xmitqueue, (void *)&conn->ctask, Not covered by session->lock. drivers/scsi/libiscsi.c iscsi_data_xmit 590 while (__kfifo_get(conn->mgmtqueue, (void *)&conn->mtask, Not covered by session->lock. drivers/scsi/libiscsi.c iscsi_data_xmit 690 __kfifo_get(session->cmdpool.queue, (void *)&ctask, sizeof(void *)); Covered by session->lock. drivers/scsi/libiscsi.c iscsi_conn_send_generic 766 if (!__kfifo_get(session->mgmtpool.queue, Covered by session->lock. drivers/scsi/libiscsi.c iscsi_remove_task 990 __kfifo_get(fifo, (void *)&task, sizeof(void *)); \ Macro that expands to iscsi_remove_mgmt_task() and iscsi_remove_cmd_task() o iscsi_remove_mgmt_task called from iscsi_ctask_mtask_cleanup, which in turn is called from fail_command() and iscsi_eh_abort(). o fail_command() comment indicates that session lock must be held. o iscsi_eh_abort() has the session lock held. o iscsi_remove_cmd_task() called from iscsi_eh_abort(), which again has the session lock held. drivers/scsi/libiscsi.c iscsi_conn_setup 1386 if (!__kfifo_get(session->mgmtpool.queue, Covered by session->lock. drivers/scsi/libiscsi.c flush_control_queues 1546 while (__kfifo_get(conn->immqueue, (void *)&mtask, sizeof(void *)) || Covered by session->lock. (Held by caller iscsi_start_session_recovery().) drivers/scsi/libiscsi.c flush_control_queues 1547 __kfifo_get(conn->mgmtqueue, (void *)&mtask, sizeof(void *))) { Covered by session->lock. (Held by caller iscsi_start_session_recovery().) drivers/scsi/libiscsi.c fail_all_commands 1575 while (__kfifo_get(conn->xmitqueue, (void *)&ctask, sizeof(void *))) { Covered by session->lock. include/linux/kfifo.h kfifo_get 113 ret = __kfifo_get(fifo, buffer, len); Covered by fifo->lock. kernel/kfifo.c __kfifo_get 150 unsigned int __kfifo_get(struct kfifo *fifo, Covered by fifo->lock. drivers/infiniband/ulp/iser/iser_initiator.c iser_snd_completion 674 __kfifo_put(session->mgmtpool.queue, (void *)&mtask, Covered by conn->session->lock. But I have no idea what consumes the resulting message -- my guess is that it is actually going down to iscsi, based on the "conn = iser_conn->iscsi_conn" earlier in this function. drivers/scsi/iscsi_tcp.c iscsi_r2t_rsp 401 __kfifo_put(tcp_ctask->r2tqueue, (void *)&r2t, sizeof(void *)); Covered by session->lock. drivers/scsi/iscsi_tcp.c iscsi_r2t_rsp 402 __kfifo_put(conn->xmitqueue, (void *)&ctask, sizeof(void *)); Covered by session->lock. drivers/scsi/iscsi_tcp.c iscsi_tcp_mtask_xmit 1388 __kfifo_put(session->mgmtpool.queue, (void *)&conn->mtask, Covered by session->lock. drivers/scsi/iscsi_tcp.c handle_xmstate_sol_data 1716 __kfifo_put(tcp_ctask->r2tpool.queue, (void *)&r2t, sizeof(void *)); Covered by session->lock. drivers/scsi/iscsi_tcp.c iscsi_tcp_cleanup_ctask 2012 __kfifo_put(tcp_ctask->r2tpool.queue, (void *)&r2t, Covered by session->lock, at least according to the comments. (called by iscsi_tcp_cleanup_ctask(), which is called by things invoking the cleanup_cmd_task function pointer, which is invoked by fail_command(), which has a header comment demanding that session->lock be held by callers. drivers/scsi/libiscsi.c iscsi_complete_command 194 __kfifo_put(session->cmdpool.queue, (void *)&ctask, sizeof(void *)); Covered by session->lock, or at least the header comment claims that it should be called under this lock. drivers/scsi/libiscsi.c __iscsi_complete_pdu 354 __kfifo_put(session->mgmtpool.queue, Covered by session->lock by all in-tree calls, but is an exported symbol. drivers/scsi/libiscsi.c __iscsi_complete_pdu 384 __kfifo_put(session->mgmtpool.queue, Covered by session->lock by all in-tree calls, but is an exported symbol. drivers/scsi/libiscsi.c __iscsi_complete_pdu 703 __kfifo_put(conn->xmitqueue, (void *)&ctask, sizeof(void *)); Covered by session->lock by all in-tree calls, but is an exported symbol. drivers/scsi/libiscsi.c iscsi_conn_send_generic 808 __kfifo_put(conn->immqueue, (void *)&mtask, sizeof(void *)); Not covered by session->lock. drivers/scsi/libiscsi.c iscsi_conn_send_generic 810 __kfifo_put(conn->mgmtqueue, (void *)&mtask, sizeof(void *)); Not covered by session->lock. drivers/scsi/libiscsi.c iscsi_remove_task 998 __kfifo_put(fifo, (void *)&task, sizeof(void *)); \ Covered by session->lock, analysis is the same as for the earlier occurrence of iscsi_remove_task(). drivers/scsi/libiscsi.c iscsi_ctask_mtask_cleanup 1016 __kfifo_put(session->mgmtpool.queue, (void *)&ctask->mtask, Called from fail_command(), which has a header comment claiming that session->lock must be held, and from iscsi_eh_abort(), which has session->lock held. drivers/scsi/libiscsi.c iscsi_eh_abort 1082 __kfifo_put(conn->xmitqueue, (void *)&pending_ctask, Covered by session->lock. drivers/scsi/libiscsi.c iscsi_pool_init 1175 __kfifo_put(q->queue, (void *)&q->pool[i], sizeof(void *)); Looks like initialization code, where no-one else would have a reference to the kfifo, so should be OK. drivers/scsi/libiscsi.c iscsi_conn_setup 1406 __kfifo_put(session->mgmtpool.queue, (void *)&conn->login_mtask, Not covered by session->lock, despite other __kfifo operations being covered by this lock elsewhere in this function. drivers/scsi/libiscsi.c iscsi_conn_teardown 1478 __kfifo_put(session->mgmtpool.queue, (void *)&conn->login_mtask, Covered by session->lock. drivers/scsi/libiscsi.c flush_control_queues 1551 __kfifo_put(session->mgmtpool.queue, (void *)&mtask, Covered by session->lock. (Held by caller iscsi_start_session_recovery().) drivers/scsi/libiscsi.c flush_control_queues 1562 __kfifo_put(session->mgmtpool.queue, (void *)&mtask, Covered by session->lock. (Held by caller iscsi_start_session_recovery().) include/linux/kfifo.h kfifo_put 89 ret = __kfifo_put(fifo, buffer, len); Covered by fifo->lock. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] memory ordering in __kfifo primitives 2006-08-10 0:33 ` Paul E. McKenney @ 2006-08-10 5:48 ` Mike Christie 2006-08-10 13:41 ` Paul E. McKenney 0 siblings, 1 reply; 14+ messages in thread From: Mike Christie @ 2006-08-10 5:48 UTC (permalink / raw) To: paulmck Cc: stelian, linux-kernel, akpm, paulus, anton, open-iscsi, pradeep, mashirle Paul E. McKenney wrote: > OK, it appears that we are even. I forgot to attach the promised > analysis of the callers to __kfifo_put() and __kfifo_get(), and > the open-iscsi@googlegroups.com email address listed as maintainer > in drivers/scsi/libiscsi.c bounces complaining that, as a non-member, > I am not allowed to send it email. ;-) Sorry about that. I do not have any control over the email list. I will change the maintainer info entry to indicate that users should just send mail to me or linux-scsi. > > Anyway, this time the analysis really is attached, sorry for my confusion! > We have change the code a little since the analysis was made. But, it does not really matter much now. I am fine with us just grabbing the session lock or xmitmitex (I will send a patch and test it as well) if your barrier patch is not accepted. We grab the session lock in the fast path now so there is not much benefit left for us. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] memory ordering in __kfifo primitives 2006-08-10 5:48 ` Mike Christie @ 2006-08-10 13:41 ` Paul E. McKenney 2006-08-10 14:26 ` Stelian Pop 0 siblings, 1 reply; 14+ messages in thread From: Paul E. McKenney @ 2006-08-10 13:41 UTC (permalink / raw) To: Mike Christie Cc: stelian, linux-kernel, akpm, paulus, anton, open-iscsi, pradeep, mashirle On Thu, Aug 10, 2006 at 01:48:02AM -0400, Mike Christie wrote: > Paul E. McKenney wrote: > > OK, it appears that we are even. I forgot to attach the promised > > analysis of the callers to __kfifo_put() and __kfifo_get(), and > > the open-iscsi@googlegroups.com email address listed as maintainer > > in drivers/scsi/libiscsi.c bounces complaining that, as a non-member, > > I am not allowed to send it email. ;-) > > Sorry about that. I do not have any control over the email list. I will > change the maintainer info entry to indicate that users should just send > mail to me or linux-scsi. Sounds good! > > Anyway, this time the analysis really is attached, sorry for my confusion! > > We have change the code a little since the analysis was made. But, it > does not really matter much now. I am fine with us just grabbing the > session lock or xmitmitex (I will send a patch and test it as well) if > your barrier patch is not accepted. We grab the session lock in the fast > path now so there is not much benefit left for us. I am happy to go either way -- the patch with the memory barriers (which does have the side-effect of slowing down kfifo_get() and kfifo_put(), by the way), or a patch removing the comments saying that it is OK to invoke __kfifo_get() and __kfifo_put() without locking. Any other thoughts on which is better? (1) the memory barriers or (2) requiring the caller hold appropriate locks across calls to __kfifo_get() and __kfifo_put()? Thanx, Paul ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] memory ordering in __kfifo primitives 2006-08-10 13:41 ` Paul E. McKenney @ 2006-08-10 14:26 ` Stelian Pop 2006-08-10 15:39 ` Paul E. McKenney 0 siblings, 1 reply; 14+ messages in thread From: Stelian Pop @ 2006-08-10 14:26 UTC (permalink / raw) To: paulmck Cc: Mike Christie, linux-kernel, akpm, paulus, anton, open-iscsi, pradeep, mashirle Le jeudi 10 août 2006 à 06:41 -0700, Paul E. McKenney a écrit : > I am happy to go either way -- the patch with the memory barriers > (which does have the side-effect of slowing down kfifo_get() and > kfifo_put(), by the way), or a patch removing the comments saying > that it is OK to invoke __kfifo_get() and __kfifo_put() without > locking. > > Any other thoughts on which is better? (1) the memory barriers or > (2) requiring the caller hold appropriate locks across calls to > __kfifo_get() and __kfifo_put()? If someone wants to use explicit locking, he/she can go with kfifo_get() instead of the __ version. I'd rather keep the __kfifo_get() and __kfifo_put() functions lockless, so I say go for (1) even if there is a tiny price to pay for corectness. Stelian. -- Stelian Pop <stelian@popies.net> ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] memory ordering in __kfifo primitives 2006-08-10 14:26 ` Stelian Pop @ 2006-08-10 15:39 ` Paul E. McKenney 2006-08-10 15:47 ` Stelian Pop 0 siblings, 1 reply; 14+ messages in thread From: Paul E. McKenney @ 2006-08-10 15:39 UTC (permalink / raw) To: Stelian Pop Cc: Mike Christie, linux-kernel, akpm, paulus, anton, open-iscsi, pradeep, mashirle On Thu, Aug 10, 2006 at 04:26:53PM +0200, Stelian Pop wrote: > Le jeudi 10 août 2006 à 06:41 -0700, Paul E. McKenney a écrit : > > > I am happy to go either way -- the patch with the memory barriers > > (which does have the side-effect of slowing down kfifo_get() and > > kfifo_put(), by the way), or a patch removing the comments saying > > that it is OK to invoke __kfifo_get() and __kfifo_put() without > > locking. > > > > Any other thoughts on which is better? (1) the memory barriers or > > (2) requiring the caller hold appropriate locks across calls to > > __kfifo_get() and __kfifo_put()? > > If someone wants to use explicit locking, he/she can go with kfifo_get() > instead of the __ version. However, the kfifo_get()/kfifo_put() interfaces use the internal lock, which cannot be used by the caller to protect other code surrounding the call to kfifo_get()/kfifo_put(). See for example the ISCSI use, where they have a session->lock that, among other things, protects their __kfifo_get()/__kfifo_put() calls. > I'd rather keep the __kfifo_get() and __kfifo_put() functions lockless, > so I say go for (1) even if there is a tiny price to pay for corectness. If we require the caller to supply the locks for __kfifo_get() and __kfifo_put(), then we have -both- correctness -and- better performance. And the only current user of __kfifo_get()/__kfifo_put() stated that they could easily expand their session->lock to cover all such calls, and that doing so would not hurt their performance. So, are you sure? And if so, why? Thanx, Paul ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] memory ordering in __kfifo primitives 2006-08-10 15:39 ` Paul E. McKenney @ 2006-08-10 15:47 ` Stelian Pop 2006-08-10 16:11 ` Paul E. McKenney 0 siblings, 1 reply; 14+ messages in thread From: Stelian Pop @ 2006-08-10 15:47 UTC (permalink / raw) To: paulmck Cc: Mike Christie, linux-kernel, akpm, paulus, anton, open-iscsi, pradeep, mashirle Le jeudi 10 août 2006 à 08:39 -0700, Paul E. McKenney a écrit : > On Thu, Aug 10, 2006 at 04:26:53PM +0200, Stelian Pop wrote: > > Le jeudi 10 août 2006 à 06:41 -0700, Paul E. McKenney a écrit : > > > > > I am happy to go either way -- the patch with the memory barriers > > > (which does have the side-effect of slowing down kfifo_get() and > > > kfifo_put(), by the way), or a patch removing the comments saying > > > that it is OK to invoke __kfifo_get() and __kfifo_put() without > > > locking. > > > > > > Any other thoughts on which is better? (1) the memory barriers or > > > (2) requiring the caller hold appropriate locks across calls to > > > __kfifo_get() and __kfifo_put()? > > > > If someone wants to use explicit locking, he/she can go with kfifo_get() > > instead of the __ version. > > However, the kfifo_get()/kfifo_put() interfaces use the internal lock, ... and the internal lock can be supplied by the user at kfifo_alloc() time. Stelian. -- Stelian Pop <stelian@popies.net> ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] memory ordering in __kfifo primitives 2006-08-10 15:47 ` Stelian Pop @ 2006-08-10 16:11 ` Paul E. McKenney 2006-08-10 16:23 ` Stelian Pop 0 siblings, 1 reply; 14+ messages in thread From: Paul E. McKenney @ 2006-08-10 16:11 UTC (permalink / raw) To: Stelian Pop Cc: Mike Christie, linux-kernel, akpm, paulus, anton, open-iscsi, pradeep, mashirle On Thu, Aug 10, 2006 at 05:47:22PM +0200, Stelian Pop wrote: > Le jeudi 10 août 2006 à 08:39 -0700, Paul E. McKenney a écrit : > > On Thu, Aug 10, 2006 at 04:26:53PM +0200, Stelian Pop wrote: > > > Le jeudi 10 août 2006 à 06:41 -0700, Paul E. McKenney a écrit : > > > > > > > I am happy to go either way -- the patch with the memory barriers > > > > (which does have the side-effect of slowing down kfifo_get() and > > > > kfifo_put(), by the way), or a patch removing the comments saying > > > > that it is OK to invoke __kfifo_get() and __kfifo_put() without > > > > locking. > > > > > > > > Any other thoughts on which is better? (1) the memory barriers or > > > > (2) requiring the caller hold appropriate locks across calls to > > > > __kfifo_get() and __kfifo_put()? > > > > > > If someone wants to use explicit locking, he/she can go with kfifo_get() > > > instead of the __ version. > > > > However, the kfifo_get()/kfifo_put() interfaces use the internal lock, > > ... and the internal lock can be supplied by the user at kfifo_alloc() > time. Would that really work for them? Looks to me like it would result in self-deadlock if they passed in session->lock. Or did you have something else in mind for them? These are the __kfifo_get() and __kfifo_put() uses in: drivers/scsi/iscsi_tcp.c drivers/scsi/libiscsi.c drivers/infiniband/ulp/iser/iser_initiator.c Thanx, Paul ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] memory ordering in __kfifo primitives 2006-08-10 16:11 ` Paul E. McKenney @ 2006-08-10 16:23 ` Stelian Pop 2006-08-10 16:47 ` Paul E. McKenney 0 siblings, 1 reply; 14+ messages in thread From: Stelian Pop @ 2006-08-10 16:23 UTC (permalink / raw) To: paulmck Cc: Mike Christie, linux-kernel, akpm, paulus, anton, open-iscsi, pradeep, mashirle Le jeudi 10 août 2006 à 09:11 -0700, Paul E. McKenney a écrit : > On Thu, Aug 10, 2006 at 05:47:22PM +0200, Stelian Pop wrote: > > Le jeudi 10 août 2006 à 08:39 -0700, Paul E. McKenney a écrit : > > > On Thu, Aug 10, 2006 at 04:26:53PM +0200, Stelian Pop wrote: > > > > Le jeudi 10 août 2006 à 06:41 -0700, Paul E. McKenney a écrit : > > > > > > > > > I am happy to go either way -- the patch with the memory barriers > > > > > (which does have the side-effect of slowing down kfifo_get() and > > > > > kfifo_put(), by the way), or a patch removing the comments saying > > > > > that it is OK to invoke __kfifo_get() and __kfifo_put() without > > > > > locking. > > > > > > > > > > Any other thoughts on which is better? (1) the memory barriers or > > > > > (2) requiring the caller hold appropriate locks across calls to > > > > > __kfifo_get() and __kfifo_put()? > > > > > > > > If someone wants to use explicit locking, he/she can go with kfifo_get() > > > > instead of the __ version. > > > > > > However, the kfifo_get()/kfifo_put() interfaces use the internal lock, > > > > ... and the internal lock can be supplied by the user at kfifo_alloc() > > time. > > Would that really work for them? Looks to me like it would result > in self-deadlock if they passed in session->lock. Yeah, it will deadlock if the lock is already taken before calling __kfifo_get and __kfifo_put. > Or did you have something else in mind for them? What I had in mind is to replace all occurences of: kfifo_alloc(..., NULL); ... spin_lock(&session->lock) __kfifo_get() spin_unlock() with the simpler: kfifo_alloc(..., &session->lock) ... kfifo_get() As for the occurences of: ... spin_lock(&session->lock) do_something(); __kifo_get(); well, there is not much we can do about them... Let's take this problem differently: is a memory barrier cheaper than a spinlock ? If the answer is yes as I suspect, why should the kfifo API force the user to take a spinlock ? Stelian. -- Stelian Pop <stelian@popies.net> ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] memory ordering in __kfifo primitives 2006-08-10 16:23 ` Stelian Pop @ 2006-08-10 16:47 ` Paul E. McKenney 2006-08-10 20:27 ` Stelian Pop 0 siblings, 1 reply; 14+ messages in thread From: Paul E. McKenney @ 2006-08-10 16:47 UTC (permalink / raw) To: Stelian Pop Cc: Mike Christie, linux-kernel, akpm, paulus, anton, open-iscsi, pradeep, mashirle On Thu, Aug 10, 2006 at 06:23:04PM +0200, Stelian Pop wrote: > Le jeudi 10 août 2006 à 09:11 -0700, Paul E. McKenney a écrit : > > On Thu, Aug 10, 2006 at 05:47:22PM +0200, Stelian Pop wrote: > > > Le jeudi 10 août 2006 à 08:39 -0700, Paul E. McKenney a écrit : > > > > On Thu, Aug 10, 2006 at 04:26:53PM +0200, Stelian Pop wrote: > > > > > Le jeudi 10 août 2006 à 06:41 -0700, Paul E. McKenney a écrit : > > > > > > > > > > > I am happy to go either way -- the patch with the memory barriers > > > > > > (which does have the side-effect of slowing down kfifo_get() and > > > > > > kfifo_put(), by the way), or a patch removing the comments saying > > > > > > that it is OK to invoke __kfifo_get() and __kfifo_put() without > > > > > > locking. > > > > > > > > > > > > Any other thoughts on which is better? (1) the memory barriers or > > > > > > (2) requiring the caller hold appropriate locks across calls to > > > > > > __kfifo_get() and __kfifo_put()? > > > > > > > > > > If someone wants to use explicit locking, he/she can go with kfifo_get() > > > > > instead of the __ version. > > > > > > > > However, the kfifo_get()/kfifo_put() interfaces use the internal lock, > > > > > > ... and the internal lock can be supplied by the user at kfifo_alloc() > > > time. > > > > Would that really work for them? Looks to me like it would result > > in self-deadlock if they passed in session->lock. > > Yeah, it will deadlock if the lock is already taken before calling > __kfifo_get and __kfifo_put. > > > Or did you have something else in mind for them? > > What I had in mind is to replace all occurences of: > kfifo_alloc(..., NULL); > ... > spin_lock(&session->lock) > __kfifo_get() > spin_unlock() > > with the simpler: > kfifo_alloc(..., &session->lock) > ... > kfifo_get() Fair enough! > As for the occurences of: > ... > spin_lock(&session->lock) > do_something(); > __kifo_get(); > > well, there is not much we can do about them... Agreed! > Let's take this problem differently: is a memory barrier cheaper than a > spinlock ? Almost always, yes. But a spinlock is cheaper than a spinlock plus a pair of memory barriers. > If the answer is yes as I suspect, why should the kfifo API force the > user to take a spinlock ? My concern is that currently a majority of the calls to __kfifo_{get,put}() are already holding a spinlock. But if you could send me your tests for lock-free __kfifo_{get,put}(), I would be happy to run them on weak-memory-consistency model machines with the memory barriers. And without the memory barriers -- we need a test that fails in the latter case to prove that the memory barriers really are in the right place and that all of them are present. Does this sound reasonable? Thanx, Paul ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] memory ordering in __kfifo primitives 2006-08-10 16:47 ` Paul E. McKenney @ 2006-08-10 20:27 ` Stelian Pop 2006-08-10 20:54 ` Paul E. McKenney 0 siblings, 1 reply; 14+ messages in thread From: Stelian Pop @ 2006-08-10 20:27 UTC (permalink / raw) To: paulmck; +Cc: Mike Christie, linux-kernel, akpm, paulus, anton, pradeep, mashirle [open-iscsi@googlegroups.com bouncing, removed from CC:] Le jeudi 10 août 2006 à 09:47 -0700, Paul E. McKenney a écrit : > > Let's take this problem differently: is a memory barrier cheaper than a > > spinlock ? > > Almost always, yes. But a spinlock is cheaper than a spinlock plus > a pair of memory barriers. Right, but I think we're optimizing too much here. > > If the answer is yes as I suspect, why should the kfifo API force the > > user to take a spinlock ? > > My concern is that currently a majority of the calls to __kfifo_{get,put}() > are already holding a spinlock. > > But if you could send me your tests for lock-free __kfifo_{get,put}(), > I would be happy to run them on weak-memory-consistency model machines > with the memory barriers. And without the memory barriers -- we need > a test that fails in the latter case to prove that the memory barriers > really are in the right place and that all of them are present. > > Does this sound reasonable? It would sound reasonable if I had any tests to send to you :) Since I don't have any and since you're the one proposing the change, I guess it's up to you to write them. :) Stelian. -- Stelian Pop <stelian@popies.net> ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] memory ordering in __kfifo primitives 2006-08-10 20:27 ` Stelian Pop @ 2006-08-10 20:54 ` Paul E. McKenney 0 siblings, 0 replies; 14+ messages in thread From: Paul E. McKenney @ 2006-08-10 20:54 UTC (permalink / raw) To: Stelian Pop Cc: Mike Christie, linux-kernel, akpm, paulus, anton, pradeep, mashirle On Thu, Aug 10, 2006 at 10:27:42PM +0200, Stelian Pop wrote: > [open-iscsi@googlegroups.com bouncing, removed from CC:] > > Le jeudi 10 août 2006 à 09:47 -0700, Paul E. McKenney a écrit : > > > > Let's take this problem differently: is a memory barrier cheaper than a > > > spinlock ? > > > > Almost always, yes. But a spinlock is cheaper than a spinlock plus > > a pair of memory barriers. > > Right, but I think we're optimizing too much here. That was in fact my point initially -- why not just require locking, either that registered at kfifo_alloc() time or a separately acquired lock? > > > If the answer is yes as I suspect, why should the kfifo API force the > > > user to take a spinlock ? > > > > My concern is that currently a majority of the calls to __kfifo_{get,put}() > > are already holding a spinlock. > > > > But if you could send me your tests for lock-free __kfifo_{get,put}(), > > I would be happy to run them on weak-memory-consistency model machines > > with the memory barriers. And without the memory barriers -- we need > > a test that fails in the latter case to prove that the memory barriers > > really are in the right place and that all of them are present. > > > > Does this sound reasonable? > > It would sound reasonable if I had any tests to send to you :) > > Since I don't have any and since you're the one proposing the change, I > guess it's up to you to write them. :) Ah, but you owe a test debt from your earlier submission of kfifo! ;-) Thanx, Paul ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2006-08-10 20:53 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-08-10 0:18 [PATCH] memory ordering in __kfifo primitives Paul E. McKenney 2006-08-10 0:29 ` Andrew Morton 2006-08-10 1:01 ` Paul E. McKenney 2006-08-10 0:33 ` Paul E. McKenney 2006-08-10 5:48 ` Mike Christie 2006-08-10 13:41 ` Paul E. McKenney 2006-08-10 14:26 ` Stelian Pop 2006-08-10 15:39 ` Paul E. McKenney 2006-08-10 15:47 ` Stelian Pop 2006-08-10 16:11 ` Paul E. McKenney 2006-08-10 16:23 ` Stelian Pop 2006-08-10 16:47 ` Paul E. McKenney 2006-08-10 20:27 ` Stelian Pop 2006-08-10 20:54 ` Paul E. McKenney
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox