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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).