From: Andi Kleen <andi@firstfloor.org>
To: ram.vepa@neterion.com
Cc: Netdev <netdev@vger.kernel.org>,
David Miller <davem@davemloft.net>,
Jeff Garzik <jgarzik@pobox.com>
Subject: Re: [net-2.6 PATCH 6/10] Neterion: New driver: Hardware init & configuration
Date: Tue, 17 Mar 2009 02:26:56 +0100 [thread overview]
Message-ID: <87bps12b33.fsf@basil.nowhere.org> (raw)
In-Reply-To: <1237018885.4966.431.camel@flash> (Ramkrishna Vepa's message of "14 Mar 2009 00:21:44 -0800")
Ramkrishna Vepa <ram.vepa@neterion.com> writes:
> +struct __hw_channel*
> +__hw_channel_allocate(
> + struct __hw_device *hldev,
> + struct __hw_vpath_handle *vph,
> + enum __hw_channel_type type,
> + u32 length,
> + u32 alloc_work_array,
> + u32 alloc_free_array,
> + u32 alloc_reserve_array,
> + u32 per_dtr_space,
> + void *userdata)
Having so many arguments in a function is usually a clear sign that it needs
to be refactored into smaller functions.
> + channel = (struct __hw_channel *) vmalloc(size);
You seem to use vmalloc nearly everywhere. First that has a lot of
overhead (rounds up to pages, flushes TLBs) and also will cause more
TLB misses. It's better to avoid it when not absolutely needed.
> + vxge_assert(channel != NULL);
> +
> + hldev = (struct __hw_device *)channel->devh;
That assert is pretyt pointless because you'll just get a NULL pointer
reference next. Same true all over. asserts (or rather BUG_ON) only
make sense when they check for something that's not nearly obvious
given a oops.
> + while (next_ptr != 0) {
> +
> + cap_id = VXGE_HW_PCI_CAP_ID((((u8 *)pci_config) + next_ptr));
> +
> + switch (cap_id) {
> +
> + case VXGE_HW_PCI_CAP_ID_PM:
> + hldev->pci_caps.pm_cap_offset = next_ptr;
This all could be done much shorter with a table.
> + if (VXGE_HW_PCI_CONFIG_SPACE_SIZE <= 0x100)
> + goto exit;
> +
> + next_ptr = 0x100;
Such magic numbers are frowned upon.
Also in general you should use the pci capabilities accessor functions
provided by the PCI layer.
> + break;
> + case VXGE_HW_PCI_EXT_CAP_ID_DSN:
> + hldev->pci_e_ext_caps.dsn_cap_offset = next_ptr;
> + break;
> + case VXGE_HW_PCI_EXT_CAP_ID_PWR:
> + hldev->pci_e_ext_caps.pwr_budget_cap_offset = next_ptr;
> + break;
> +
> + default:
> +
> + break;
> + }
> +
> + next_ptr = (u16)VXGE_HW_PCI_EXT_CAP_NEXT(
> + *(u32 *)(((u8 *)pci_config) + next_ptr));
Especially the patch orgies are scary. Does that really use readl() et.al.
correctly? I doubt it. Again this should use the pci layer code for this.
> +/**
> + * vxge_hw_device_private_set - Set driver context.
> + * @hldev: HW device handle.
> + * @data: pointer to driver context
> + *
> + * Use HW device to set driver context.
> + *
> + * See also: vxge_hw_device_private_get()
> + */
> +void vxge_hw_device_private_set(struct __hw_device *hldev, void *data)
> +{
> + hldev->upper_layer_data = data;
> +}
Such wrappers are not encouraged in Linux code, which aims to do with
only necessary abstraction. Lots of occurrences.
> +
> +#ifdef VXGE_HW_INTERNAL_COMPILER_ERROR
> +
> +#pragma optimize("", off)
> +
> +#endif
That's not for gcc isn't it?
> +/*
> + * __hw_ring_block_memblock_idx - Return the memblock index
> + * @block: Virtual address of memory block
> + *
> + * This function returns the index of memory block
> + */
> +static inline u32
> +__hw_ring_block_memblock_idx(
> + u8 (block)[VXGE_HW_BLOCK_SIZE])
> +{
> + return (u32)*((u64 *)((u8 *)block +
> + VXGE_HW_RING_MEMBLOCK_IDX_OFFSET));
Is that readl/writel clean again?
In general your driver looks like it could use a pass with sparse's
__iomem checking (make V=1)
> +static enum vxge_hw_status
> +__hw_ring_mempool_item_alloc(
> + struct vxge_hw_mempool *mempoolh,
> + void *memblock,
> + u32 memblock_index,
> + struct vxge_hw_mempool_dma *dma_object,
> + void *item,
> + u32 index,
> + u32 is_last,
> + void *userdata)
Again far too many arguments.
Stopped reading for now, but that file needs a lot of work in general.
-Andi
next prev parent reply other threads:[~2009-03-17 1:29 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-03-14 8:21 [net-2.6 PATCH 6/10] Neterion: New driver: Hardware init & configuration Ramkrishna Vepa
2009-03-16 21:42 ` Ben Hutchings
2009-03-17 1:26 ` Andi Kleen [this message]
2009-03-17 3:25 ` Ramkrishna Vepa
2009-03-17 3:34 ` Ben Hutchings
2009-03-17 5:57 ` [net-2.6 PATCH 6/10] Neterion: New driver: Hardware init &configuration Ramkrishna Vepa
2009-03-17 10:52 ` [net-2.6 PATCH 6/10] Neterion: New driver: Hardware init & configuration Andi Kleen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87bps12b33.fsf@basil.nowhere.org \
--to=andi@firstfloor.org \
--cc=davem@davemloft.net \
--cc=jgarzik@pobox.com \
--cc=netdev@vger.kernel.org \
--cc=ram.vepa@neterion.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.