Re: pci_probe function is atomic?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, May 4, 2009 at 9:40 PM, Greg KH <greg@xxxxxxxxx> wrote:
> On Mon, May 04, 2009 at 09:16:54PM +0530, arun c wrote:
>> On Mon, May 4, 2009 at 8:19 PM, Greg KH <greg@xxxxxxxxx> wrote:
>> > On Mon, May 04, 2009 at 12:47:44PM +0530, arun c wrote:
>> >> Hi all,
>> >>
>> >> I have a dual core system(I am running kernel  2.6.22, 2.6.16, or 2.6.27  ),
>> >> where I can put a maximum of 8 similar PCI cards.
>> >>
>> >> So in my driver I register ('pci_register_driver()') with device ID and
>> >> vender ID(same for all 8 cards).
>> >>
>> >> I need to access a global data from the probe functions. If there are
>> >> 8 PCI devices detected probe function is called one after another?
>> >>
>> >> or is there any chance that they execute in parallel?
>> >
>> > Yes, in the future (and in some types of configurations today), it could
>> > execute in parallel.
>> >
>> > Just use a lock to control access to your shared global data structure.
>> >
>> > But you might wish to revisit your usage of global data, why can't it be
>> > a per-device field that is dynamically created for every individual
>> > device?  That would scale much better, right?
>>
>> I am using a character device interface to talk to my devices.
>> only one character driver controlling all the PCI devices.
>
> Only 1?  That seems like a design mistake :)

But LDD3 says "but most devices that you will see are still organized on the
one-major-one-driver principle", that's why I decided to use one major
no for all the devices

And my module init looks like this

static int __init my_init_module(void)
{
        struct cdev *cdev = &my_cdev; /* defined global */
        dev_t dev_id;
        int err;

        if (major) {
                dev_id = MKDEV(major, 0);
                err = register_chrdev_region(dev_id, 32, DEVICE_NAME);
        } else {
                err = alloc_chrdev_region(&dev_id, 0, 32, DEVICE_NAME);
                major = MAJOR(dev_id);
        }

        if (err)
                return err;

        cdev_init(cdev, &my_fops);
        cdev->owner = THIS_MODULE;
        cdev->ops = &my_fops;
        err = cdev_add(cdev, dev_id, 32);
        if (err)
                return err;
        err = pci_register_driver(&my_pci_driver);
        if (err)
                 goto clean_cdev;

        return 0;

clean_cdev:
        cdev_del(cdev);
        unregister_chrdev_region(dev_id, 32);
        return err;

Are you saying that this is wrong?, and I should use only
pci_register_driver() in my init module and use individual
character drivers for all the pci devices probed?

>
>> Even if I use per-device fields, I need to store these pointers some
>> where right?
>
> What's wrong with the per-device structure the kernel gives you?  That
> is how it is supposed to be done.
>
>> lock
>> global_array[index++] = pointer_to_pci_data_of_just_now_probed_device;
>> unlock
>
> Ick, no, don't do that!
>
>> Other wise I must be calling register_chrdev() in all the device probes and fill
>> the chrdev private data field. This will end up in too many major no.
>> for just one
>> type of device, I think that is not fair.
>>
>> So I thought I can escape without locks even if I use global data, if the
>> pci_probe function is atomic!!!!!!!!!!
>
> disconnect might not be atomic either, right?
>
> And again, you might wish to rethink your design decisions, it doesn't
> seem to match up with the "traditional" PCI driver design for Linux.
>
I am confused now :)

Could you please point me to some reference source files?

Regards,
Arun C
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux