Subject: Re: fixing sk_stream_rfree()

From: Ingo Oeser <[email-masked]>
Date: Tue, 18 Apr 2006 13:49:36 +0200

Hi David,

You wrote:
> 2) We can't turn sk_forward_alloc easily into an atomic_t.  The
>    masking operation in __sk_stream_mem_reclaim() does not translate
>    readily into an atomic_t op:
> 
> 		sk->sk_forward_alloc &= SK_STREAM_MEM_QUANTUM - 1;
> 
>    That line has always driven me nuts, but I know that it is there
>    to handle partial page allocations existing when that function
>    is called.
> 
> I guess for #2 we could change those two lines into:
> 
> 		int n = atomic_read(&sk->sk_forward_alloc) /
> 				SK_STREAM_MEM_QUANTUM;
> 
> 		atomic_sub(n, sk->sk_prot->memory_allocated);
> 		sk->sk_forward_alloc -= n * SK_STREAM_MEM_QUANTUM;
> 
> in order to make it "atomic_t op" translatable.

It is possible. Just view this as an register with size SK_STREAM_MEM_QUANTUM.

Mask on every read and always after the read.
Always add/subtract the intended value.
Wraparound happens within the modulo/mask value.

This works without problems as long as SK_STREAM_MEM_QUANTUM 
is a power of two. If not, just use modulo arithmetics.

The non-atomic wrapround doesn't change the atomic nature of
read, add, sub. Only problem is atomic_dec_and_test() or similiar ops.

Regards

Ingo Oeser